Home > Net >  Does left shift operator wrap the bits around?
Does left shift operator wrap the bits around?

Time:07-22

If my understanding of the left shift operator and little endianness is correct, then the value of x in the following should be 0 on little endian machines.

uint64_t x = ((uint64_t)1<<63);

(uint64_t)1 in memory will look like 0x0100000000000000 and left shifting by 63 will change that to 0x0000000000000000 which is 0. So x should be 0. But when I run the following on my x86-64 machine

int main()
{
    uint64_t x = ((uint64_t)1)<<63;
    printf("%lu\n", x);
}

The output I get is 9223372036854775808. What am I getting wrong here?

CodePudding user response:

(uint64_t)1 has the value 0x0000000000000001. How this value is represented on the memory shoudln't affect the calculation.

Shifting this value to left by 63 yields 0x8000000000000000, which is 9223372036854775808 in decimal.

What you did wrong is the format specifier. You should use PRIu64 (defined in inttypes.h) to print uint64_t. %lu is for unsigned long and passing data having wrong type invokes undefined behavior.

#include <stdio.h>
#include <inttypes.h>

int main(void)
{
    uint64_t x = ((uint64_t)1)<<63;
    printf("%" PRIu64 "\n", x);
}

CodePudding user response:

The shift operator does not depend on little or big endianness. For unsigned integers it evaluates like (The C Standard, 6.5.7 Bitwise shift operators)

4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type

That is as the arithmetic operation E1 × 2^E2.

So for example the expression

1u << 1

is equivalent to 1u * 2 (1u * 2 ^ 1).

  • Related