Monday 10 December 2012

Left shift <<, Right shift >> and Unsigned right shift >>>

The left shift operator, <<, shifts all of the bits in a value to the left a specified number of times. For each shift left, the high-order bit is shifted out (and lost), and a zero is brought in on the right.

For example,

int value = -49;
System.out.println(Integer.toBinaryString(value));
System.out.println(Integer.toBinaryString(value << 1));
System.out.println(Integer.toBinaryString(value << 8));
System.out.println(Integer.toBinaryString(value << 31));
System.out.println(Integer.toBinaryString(value << 32));

Result is:

11111111111111111111111111001111
11111111111111111111111110011110
11111111111111111100111100000000
10000000000000000000000000000000
11111111111111111111111111001111

It is interesting to note that when you left shift a value 32 bits, the result is not 0 as you may have expected. It turns out the shift distance is calculated mod 32. So value << 32 is exactly the same as value << 0 (do nothing).

What about left shift a negative value?

System.out.println(Integer.toBinaryString(value << -1));
System.out.println(Integer.toBinaryString(value << -24));

Result is:

10000000000000000000000000000000
11111111111111111100111100000000

You can see value << -1 is exactly the same as value << 31, value << -24 is exactly the same as value << 8.

The right shift operator, >>, shifts all of the bits in a value to the right a specified number of times. For each right left, the low-order bit is shifted out (and lost), and a zero is brought in on the left if the top bit is 0 (positive number), a one is brought in on the left if the top bit is 1(negative number).


int value = -49;
System.out.println(Integer.toBinaryString(value));
System.out.println(Integer.toBinaryString(value >> 1));
System.out.println(Integer.toBinaryString(value >> 8));
System.out.println(Integer.toBinaryString(value >> 31));
System.out.println(Integer.toBinaryString(value >> 32));
value = 49;
System.out.println(Integer.toBinaryString(value));
System.out.println(Integer.toBinaryString(value >> 1));
System.out.println(Integer.toBinaryString(value >> 8));
System.out.println(Integer.toBinaryString(value >> 31));
System.out.println(Integer.toBinaryString(value >> 32));

Result is:

11111111111111111111111111001111
11111111111111111111111111100111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111001111
110001
11000
0
0
110001

When the shift distance is 32, just like left shift operation, it has no effect. When the shift distance is negative, the behavior is similar to that of left shift operation --- e.g. value >> -1 is the same as value >> 31.

The unsigned right shift operator, >>>, shifts all of the bits in a value to the right a specified number of times. For each right left, the low-order bit is shifted out (and lost), and a zero is always brought in on the left regardless the top bit is 0 (positive number) or 1 (negative number).


int value = -49;
System.out.println(Integer.toBinaryString(value));
System.out.println(Integer.toBinaryString(value >>> 1));
System.out.println(Integer.toBinaryString(value >>> 8));
System.out.println(Integer.toBinaryString(value >>> 31));
System.out.println(Integer.toBinaryString(value >>> 32));
value = 49;
System.out.println(Integer.toBinaryString(value));
System.out.println(Integer.toBinaryString(value >>> 1));
System.out.println(Integer.toBinaryString(value >>> 8));
System.out.println(Integer.toBinaryString(value >>> 31));
System.out.println(Integer.toBinaryString(value >>> 32));

Result is:

11111111111111111111111111001111
1111111111111111111111111100111
111111111111111111111111
1
11111111111111111111111111001111
110001
11000
0
0
110001