Interpreting an unsigned (long) int as signed in C ++

In Arduino C ++:

I want to rethink 32 bits of an unsigned long as long signed. The exact bits are considered to be integers 2's complement instead of unsigned integers. I don’t think that just throwing it (for a long time) will do the trick. Am I mistaken?

Or maybe the best way. I use unsigned long as a timer. Sometimes I read the current value and compare it with the previous reading (both unsigned lengths) to find out how much time has passed. I need to handle a possible overflow that will cause the current value to be less than the previous value. Interpreting both values ​​as signed lengths and subtractions seems to give the correct answer.

I tried this:

return reinterpret_cast<long>(time4) - reinterpret_cast<long>(currTimeLo); // treat unsigned as 2 complement

but just got a compiler error:

Arduino: 1.6.7 (Mac OS X), Tip: "Arduino Nano, ATmega328" Invalid listing from type "long unsigned int" for input "long int"

+4
source share
3 answers

As for the deeper / original problem of checking how much time has passed by comparing two unsigned counters, where there could be one single restriction:

just subtract the earliest of the latter using unsigned arithmetic.

Assuming yours currTimeLois the counter value for the current time, and time4is some earlier value, and both are of unsigned type (or one of the signed types promotes the unsigned type of the other),

return currTimeLo - time4;

, ++ , 2 n n - .

, 1 , . .


, 2:

, . Y X/Y. , , X, (. ).


, , :

, ++ , .

; , , . ++ static_cast. ,

return static_cast<long>(time4) - static_cast<long>(currTimeLo);

, Arduino .

, , , , .

  • reinterpret_cast,

  • , , memcpy, , ,

  • UB,

  • , , .

, - SO. , , , , , . static_cast, .

+2

static_cast, - :

static_cast<signed long>(your_unsigned_long)
0

2- , 2 ^ n, .. , . , (long)0xFFFFFFFFu -1

, , 1 /. , 32 . signed , , , , . LONG_MAX - LONG_MIN LONG_MIN - LONG_MAX , long, long s

,

return static_cast<long long>(time4) - static_cast<long long>(currTimeLo);

int

if (time4 > rcurrTimeLo) // time hasn't overflowed
{
    timediff = time4 - rcurrTimeLo;
    // do something, for example set overflow flag:
    OV = 0;
}
else
{
    timediff = rcurrTimeLo - time4;
    // do something, for example set overflow flag:
    OV = 1;
}

, , 32- , 32- 64- , 8- MCU, ATmega

If you can guarantee that two operands are no more than LONG_MAX, far apart, simply static_castto long will work

return static_cast<long>(time4) - static_cast<long>(currTimeLo);
0
source

Source: https://habr.com/ru/post/1626704/


All Articles