Search code examples
c++integerintuint8t

How to turn a signed integer value to unsigned, according to its bits?


I want to turn a signed value into an unsigned one (for example, int8_t to uint8_t), but also it must keep its bits.

How can I do it?


Solution

  • In practice: you can simply assign the signed value to the uint8_t,

    u = i;
    

    or you can initialize it with the signed value,

    uint8_t u = i;
    

    This assumes a two's complement signed integer representation, which is universally used today. With that representation the bits are preserved exactly. The “in practice” qualification refers to that assumption.


    E.g., on a modern machine, the 8-bit signed representation of e.g. −42, is bitpattern number −42 + 256, which is (bitpattern number) 214. Converting that to unsigned is guaranteed by the standard to yield the same value modulo 256. And so it's the same bitpattern, namely bitpattern 214.


    Going from signed to unsigned is well defined by the standard, although the preservation of the bit pattern (1)generally is just an in-practice effect (all modern computers are designed that way). However, going in the opposite direction you encounter compiler-specific effects if the unsigned value cannot be represented. More care is needed for this conversion, because it's a matter of compiler discretion and not a practical guarantee at the hardware level.


    (1) As M.M. explains in his answer the particular signed type in your example, int8_t, is one that since C11 has been guaranteed two's complement in C. I do not see that language in the final draft of the C99 standard, so presumably it was not there in C99, and thus not in either C++11 or C++14, which are based on C99, but is probably there in C++17, which I believe is based on C11.