Reputation: 303
I am trying to have C interpret an inverted unsigned integer as an unsigned integer. How can I invert the bits of a unsigned number without C interpreting it as two’s complement?
Whenever I have an unsigned integer and I use it as a operand with the bitwise NOT operator it evaluates to a negative number as according to two’s complement. However by definition I am using an unsigned integer, a number that should not have a sign.
Below has my sandboxed code. I am currently using GCC version 9.1.1.
#include <stdio.h>
#include <stdint.h>
int main(){
uint8_t x = 1;//0000 0001
printf("NOT(%d) == %d", x, ~x);//1111 1110
}
I want the output of 254 (1111 1110) but C interprets the value as two’s complement so I get -2. Is there a way I can get C to not interpret the inverted byte as two’s complement?
Upvotes: 2
Views: 1531
Reputation: 222323
In C, when an integer narrower than an int
is used in an expression, it is automatically promoted to int
. Thus, in ~x
, the uint8_t
is automatically converted to an int
, and then the bitwise ~
is performed, and then the result is passed to printf
as an int
. So what is printed is the result of inverting all the bits of an int
, instead of just the bits of a uint8_t
.
To get a uint8_t
result, cast the expression to uint8_t
:
printf("NOT(%d) == %d", x, (uint8_t) ~x);
Note that after the uint8_t
conversion is performed, the value is again automatically promoted to an int
, so printf
receives an int
in either case. However, the conversion reduces the value to one representable in a uint8_t
, and this is the value that will be printed.
However, the conversion to uint8_t
is using an int
as the source type, so the bits of ~x
will be interpreted according to the implementation’s int
format. To get the low bits of ~x
without relying on the int
format, you can extract them with & 0xff
instead of using a cast:
printf("NOT(%d) == %d", x, ~x & 0xff);
Alternately, you can perform the bitwise ~
on an unsigned
value instead of an int
value:
printf("NOT(%d) == %d", x, (uint8_t) ~ (unsigned) x);
Upvotes: 5