Could someone explain me why:
x = x << 1;
x = x >> 1;
and:
x = (x << 1) >> 1;
produce different answers in C? x
is a *uint8_t* type (unsigned 1-byte long integer). For example when I pass it 128 (10000000)
in the first case it returns 0
(as expected most significant bit falls out) but in the second case it returns the original 128
. Why is that? I'd expect these expressions to be equivalent?
When you bitshift the result is promoted to
int
. In the first example you convert int back to uint8_t everytime, and lose the intermediate data. But in the second example you keep the int result when you shift back.This is due to integer promotions, both operands of the bit-wise shifts will be promoted to int in both cases. In the second case:
the result of
x << 1
will be an int and therefore the shifted bit will be preserved and available to the next step as an int which will shift it back again. In the first case:when you assign back to
x
you will lose the extra bits. From the draft C99 standard section6.5.7 Bit-wise shift operators
it says:The integer promotions are covered in section
6.3.1.1
Boolean, characters, and integers paragraph 2 which says:The last piece of this why does the conversion from the int value
256
to uint8_t give us0
? The conversion is covered in section6.3.1.3
Signed and unsigned integers which is under the Conversions section and says:So we have
256 - (255+1)
which is0
.