I have the following program:

int main()
{
    int64_t a = 241294423792285589;
    printf("a = %lld, a << 63 = %lld", a, a << 63);
    return 0;
}

I was expecting a << 63 to be 0, but it prints out:

a = 241294423792285589, a << 63 = -9223372036854775808

Why is this?

3 Answers

5
John On Best Solutions

If you convert these integers to signed 2's complement binary you can see why:

241294423792285589 in binary is

0000001101011001010000000000000000000000011010111111011110010101

Shifting this left by 63 spots will result in the right-most 1 ending up in the left-most binary digit:

1000000000000000000000000000000000000000000000000000000000000000

Which in 2's complement binary is -9223372036854775808.

You can find binary <-> decimal converters online (such as this one: https://www.rapidtables.com/convert/number/decimal-to-binary.html) that can help make this more clear.

Or you can even try this bitshift calculator: https://bit-calculator.com/bit-shift-calculator

4
AnT On

Your shift expression has undefined behavior. There's no value you can meaningfully expect from that shift.

In C behavior of left shift E1 << E2 for signed E1 is described by 6.5.7/4

If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

0
Luis Colorado On

The problem is that you left shift an odd number (a number with the least signifiant bit set) 63 places to the left in a 64 bit word. The value you obtain is

0b1000_0000_0000_0000_...._0000

or

0x8000000000000000

that (in two's complement) is the number you post in your question.

Anyway, shifting 63 places a signed 64bit number is undefined behaviour, so that means that you can receive anything at all... event that huge negative number.