question about endianness and shift operators

Recommended Posts

Can someone please explain how the following code works with respect to endianness and what the shift operators do:
    union {
int i;
unsigned char c[4];
};

i = 5;
//c[0] == 5;

int j = c[0] | c[1]<<8 | c[2]<<16 | c[3]<<24;
//j == 5 == i
I am assuming that an int is 32-bits and an unsigned char is 8-bits. I don't understand why this works on my machine, surely if c[0] == 5 then it is on the left-most byte of the 4 bytes, but in the assembly of j it is placed as the right-most byte. Obviously I'm not understanding something, I think its how the shift operators work is different to what I imagine. A little confused but any insight is welcome Thanks

Share on other sites
That code looks fine to me (corresponding to a little-endian architecture, such as the x86). And I doubt your confusion has anything to do with the bitshifts themselves.
Can you elaborate on exactly what you mean by left-most and right-most bytes?

Just to be clear, on a little endian machine the first character in c would be the least significant byte of the integer. So if visualized horizontally with c[0] on the left then you have an order opposite of the "normal" positional system.
So c = { 5, 0, 0, 0 } -> i = 5 and c = { 0, 0, 0, 5 } -> i = 0x05000000.

Share on other sites
"endianness" is the order that the bytes of a multi-byte value is stored in memory. "Big-endian" means that the bytes are stored in order from highest to lowest significance and "little-endian" means that the bytes are stored in order from lowest to highest significance.

Here is an example that should make things clear. Suppose we store numbers in memory as decimal digits instead of bytes. How would the number 1234 be stored? As big-endian, the digits would be stored from highest to lowest significance: 1, 2, 3, 4. As little-endian, the number would be stored from lowest to highest significance: 4, 3, 2, 1. Note that c[0] would be 1 when stored as big-endian, and 4 when stored as little-endian.

Now, how do we load a number that is stored in the opposite endianness of our machine? If we load it normally, the digits are going to be in the wrong order. To load the number we need to reverse the order of the digits. Suppose in this example, the shift operators << and >> shift left and right 1 digit. We would load a 4 digit number like this: n = c[0] | ( c[1] << 1 ) | (c[2] << 2 ) | ( c[3] << 3 ).

Share on other sites
Mr. Bolton.

That is a neat trick. I've never seen that before, and its my job to write our cross platform libraries;).

Cheers
Chris

Create an account

Register a new account

• Forum Statistics

• Total Topics
628383
• Total Posts
2982378

• 10
• 9
• 15
• 24
• 11