Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert 4 bytes char to int32 in C

Tags:

c

I first convert an int32 number to char[4] array, then convert the array back to int32 by (int *), but the number isn't the same as before:

unsigned int num = 2130706432;
unsigned int x;
unsigned char a[4];

a[0] = (num>>24) & 0xFF;
a[1] = (num>>16) & 0xFF;
a[2] = (num>>8) & 0xFF;
a[3] = num & 0xFF;

x = *(int *)a;
printf("%d\n", x);

the output is 127. And if I set num = 127, the output is 2130706432. Does anyone have ideas?

like image 418
stackunderflow Avatar asked Nov 17 '11 19:11

stackunderflow


4 Answers

Reverse the order of the a[] indexes, e.g,. a[0] -> a[3]

I think you have the endianness in reverse.

Try this:

a[3] = (num>>24) & 0xFF;
a[2] = (num>>16) & 0xFF;
a[1] = (num>>8) & 0xFF;
a[0] = num & 0xFF;
like image 78
Anthony Blake Avatar answered Oct 21 '22 21:10

Anthony Blake


To see what happens use

printf("%x\n", ...);

to print both input and output number.

Endian-independent way:

x = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3];
like image 34
Adam Trhon Avatar answered Oct 21 '22 21:10

Adam Trhon


This line is never going to work correctly on a little-endian machine:

x = *(int *)a;

You need to unpack the data before you print out the value.

like image 21
Mike Steinert Avatar answered Oct 21 '22 20:10

Mike Steinert


Your code a[0] = (num>>24) & 0xFF; takes the most significant 8 bits from num and sticks them in the first byte of a. On little endian machines the first byte holds the least signficant bits. That means that on little endian machines, this code takes the most significant 8 bits and stores them in the place where the least significant bits go, changing the value.

2130706432 is 0x7F000000 in hex, and 127 is 0x0000007F.

Also, x = *(int *)a; results in undefined behavior. Consider hardware where reading an int from an improperly aligned address causes a bus error. If a doesn't happen to be aligned properly for an int then the program would crash.

A correct approach to interpreting the bytes as an int would be std::memcpy(&x, a, sizeof x);

like image 35
bames53 Avatar answered Oct 21 '22 19:10

bames53