Does bit-shift depend on endianness?

Endianness is the way values are stored in memory. When loaded into the processor, regardless of endianness, the bit shift instruction is operating on the value in the processor's register. Therefore, loading from memory to processor is the equivalent of converting to big endian, the shifting operation comes next and then the new value is stored back in memory, which is where the little endian byte order comes into effect again.

Update, thanks to @jww: On PowerPC the vector shifts and rotates are endian sensitive. You can have a value in a vector register and a shift will produce different results on little-endian and big-endian.


No, bitshift, like any other part of C, is defined in terms of values, not representations. Left-shift by 1 is mutliplication by 2, right-shift is division. (As always when using bitwise operations, beware of signedness. Everything is most well-defined for unsigned integral types.)


Whichever shift instruction shifts out the higher-order bits first is considered the left shift. Whichever shift instruction shifts out the lower-order bits first is considered the right shift. In that sense, the behavior of >> and << for unsigned numbers will not depend on endianness.


Though the accepted answer points out that endianess is a concept from the memory view. But I don't think that answer the question directly.

Some answers tell me that bitwise operations don't depend on endianess, and the processor may represent the bytes in any other way. Anyway, it's talking about that endianess gets abstracted.

But when we do some bitwise calculations on the paper for example, don't need to state the endianess in the first place? Most times we choose an endianess implicitly.

For example, assume we have a line of code like this

0x1F & 0xEF

How would you calculate the result by hand, on a paper?

  MSB   0001 1111  LSB
        1110 1111
result: 0000 1111

So here we use a Big Endian format to do the calculation. You can also use Little Endian to calculate and get the same result.

Btw, when we write numbers in code, I think it's like a Big Endian format. 123456 or 0x1F, most significant numbers starts from the left.

Again, as soon as we write some a binary format of a value on the paper, I think we've already chosen an Endianess and we are viewing the value as we see it from the memory.

So back to the question, an shift operation << should be thought as shifting from LSB(least significant byte) to MSB(most significant byte).

Then as for the example in the question:

numb=1025

Little Endian

LSB 00000001 00000100 00000000 00000000 MSB

So << 10 would be 10bit shifting from LSB to MSB.


Comparison and << 10 operations for Little Endian format step by step:

MSB                                        LSB
    00000000  00000000  00000100  00000001  numb(1025)
    00000000  00010000  00000100  00000000  << 10

LSB                                        MSB
    00000000  00000100  00010000  00000000 numb(1025) << 10, and put in a Little Endian Format

LSB                                        MSB
    00000001  00000100  00000000  00000000 numb(1205) in Little Endian format
    00000010  00001000  00000000  00000000 << 1 
    00000100  00010000  00000000  00000000 << 2 
    00001000  00100000  00000000  00000000 << 3 
    00010000  01000000  00000000  00000000 << 4
    00100000  10000000  00000000  00000000 << 5
    01000000  00000000  00000001  00000000 << 6
    10000000  00000000  00000010  00000000 << 7
    00000000  00000001  00000100  00000000 << 8
    00000000  00000010  00001000  00000000 << 9
    00000000  00000100  00010000  00000000 << 10 (check this final result!)

Wow! I get the expected result as the OP described!

The problems that the OP didn't get the expected result are that:

  1. It seems that he didn't shift from LSB to MSB.

  2. When shifting bits in Little Endian format, you should realize(thank god I realize it) that:

LSB 10000000 00000000 MSB << 1 is
LSB 00000000 00000001 MSB, not LSB 01000000 00000000 MSB

Because for each individual 8bits, we are actually writing it in a MSB 00000000 LSB Big Endian format.

So it's like

LSB[ (MSB 10000000 LSB) (MSB 00000000 LSB) ]MSB


To sum up:

  1. Though bitwise operations is said to be abstracted away blablablabla..., when we calculate bitwise operations by hand, we still need to know what endianess we are using as we write down the binary format on the paper. Also we need to make sure all the operators use the same endianess.

  2. The OP didn't get the expected result is because he did the shifting wrong.

Tags:

C

Endianness