1

So I was experimenting with left shifting in Java and I found something I didn't understand. The code below describes it.

int x = -1 << 31;
System.out.print(Integer.toBinaryString(-1) + " -1\n");
System.out.print(Integer.toBinaryString(x) + " " + x + "\n");

// output
11111111111111111111111111111111 -1
10000000000000000000000000000000 -2147483648

So I just got rid of 31 1s on the left of the integer -1, and the result was what I expected. However, after I tried to left shift 1 more position, instead of getting 0, I got -1.

int x = -1 << 32; // one more left shift
System.out.print(Integer.toBinaryString(-1) + " -1\n");
System.out.print(Integer.toBinaryString(x) + " " + x + "\n");

// output
11111111111111111111111111111111 -1
11111111111111111111111111111111 -1

Then I tried left shifting the minimum integer value, -2147483648, directly by 1. And I got the expected value 0.

System.out.println(-2147483648 << 1); // the output is 0

Can someone explain to me what happened behind the scenes?

1 Answers1

0

Here's the JLS 15.19:

If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.

So -1 << 32 is the same as -1 << 0, explaining your result.

that other guy
  • 116,971
  • 11
  • 170
  • 194