I'm trying to manipulating binary numbers with c. I found a strange thing with the minimum code below. Can anyone tell me what is the difference between "+" and "|" here? Thank you!
char next_byte1 = 0b11111111;
char next_byte2 = 0b11110101;
short a = (next_byte1 << 8) | next_byte2;
short b = (next_byte1 << 8) + next_byte2;
printf("a vs b is %d ~ %d.\n", a, b);
It showed: a vs b is -11 ~ -267, which is 0b11111111 11110101 and 0b11111110 11110101. I'm very confused with this result.
The problem you are seeing is because next_byte2
is sign-extended to a full int
before doing the bitwise operation and thus is "corrupting" the high byte.
When doing bit manipulation it's better to use unsigned
types (that is actually what unsigned are to be used for). Plain char
types can be (and normally are) signed types and thus are better avoided for these uses.
char
for binary/bitwise arithmetic, because it has implementation-defined signedness and might be negative. In general, use stdint.h
over the default C types.char
is signed, then the value inside it ends up converted to -1
in two's complement during the variable initialization. This happens to next_byte1
and next_byte2
both.int
. So your -1
(0xFF) gets changed to -1
(0xFFFFFFF) before you left shift.0xFFFFFF00
.|
and +
is that the latter cares about sign, so in case of +
you end up adding negative numbers together, but in case of |
the binary representations are simply OR:ed together.You can fix the program in the following way:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint8_t next_byte1 = 0xFF;
uint8_t next_byte2 = 0xF5;
uint16_t a = (next_byte1 << 8) | next_byte2;
uint16_t b = (next_byte1 << 8) + next_byte2;
printf("a vs b is %d ~ %d.\n", a, b);
}
And now |
and +
work identically, as intended.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With