• Advertisement
Sign in to follow this  

question about endianness and shift operators

This topic is 4510 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement