I have a stream of bytes that is being read in from a socket (little endian).
Can someone tell me why only the last one of the methods below gives the correct answer?
I suspect it’s to do with the carry bit but not sure. I’ve always found that when
printing binary data in hex form.
e.g.
printf("%02X", data);
it sometimes prints out funny values with 0xff in front. The way to fix it seems to
be doing this. This still occasionally happens when data is a char data type too:
printf("%02X", data & 0xff);
Heres a simplified example from what I was seeing with my byte stream.
Where bytes would be the stream of bytes I’ve read from the socket.
int main(int argc, char* argv[])
{
union {
unsigned int num;
char bytes[4];
} x;
x.num = 500;
printf("x.num=%u\n", x.num);
unsigned int method1 = x.bytes[0] | (x.bytes[1] << 8) | (x.bytes[2] << 16) | (x.bytes[3] << 24);
printf("method1 = %u\n", method1);
unsigned int method2 = x.bytes[0] + (x.bytes[1] << 8) + (x.bytes[2] << 16) + (x.bytes[3] << 24);
printf("method2 = %u\n", method2);
unsigned int method3 = (x.bytes[0] & 0xff | (x.bytes[1] & 0xff) << 8
| (x.bytes[2] & 0xff) << 16 | (x.bytes[3] & 0xff) << 24);
printf("method3 = %u\n", method3);
return 0;
}
Which outputs:
x.num=500
method1 = 4294967284
method2 = 244
method3 = 500
Only the last extract is actually correct.
Is my method of building up the numbers the most optimal? I also tried a memcpy to a variable but again that wasn’t reliable.
When signed datatypes are being cast into higher datatypes, the most significant bit is used as a sign bit. You should have
unsigned charin your union. In your case 500 = 256 + 244 = 0x1f4 and the byte 244 has the most significant bit set, so when promoted becomes 0xfffffff4.