3 minute read

Left shift («)

How does it look?

0b00000001 << 1

What does it do?

Shifts the bits in the left operand. It shifts them to the left.

How far?

By the number of places given on the right (in the right operand).

Effects

High-order bits of the left operand (from its left-hand side) are removed (it is often being said: lost). Zeroes are shifted in from the right-hand side.

Shifting an integer left by n places is equivalent to multiplying that number by (2^n) (two to n power).

Example 1:

0b00000001 << 1 = 0b00000010

decimal version:

1 << 1 = 2

Equivalent:

left_operand = 1
n = 1
2 ^ n = 2 ^ 1 = 2

ergo

left_operand * (2 ^ n) = 1 * (2 ^ 1) = 1 * 2 = 2

Example 2:

0b00000010 << 3 = 0b00010000

decimal version:

2 << 3 = 16

Equivalent:

left_operand = 2
n = 3
2 ^ n = 2 ^ 3 = 8

ergo

left_operand * (2 ^ n) = 2 * (2 ^ 3) = 2 * 8 = 16

Constraints:

If the left operand is a long, the right operand should be between 0 and 63. Otherwise, the left operand is taken to be an int, and the right operand should be between 0 and 31.

Signed right shift (»)

How does it look?

00010000 >> 3

What does it do?

Shifts the bits in the left operand. It shifts them to the right.

How far?

By the number of places given on the right (in the right operand).

Effects

Low-order bits of the left operand (from its right-hand side) are removed (it is often being said: lost). From the left-hand side new bits are shifted in. Their value is the same as the original high-order bit of the left operand (its value before shifting has started). If the left operand is positive (starts with 0), zeroes are shifted into the place of high-order bits shifted to the right. If the left operand is negative (starts with 1), ones are shifted in.

It is called sign extension - it keeps the sign of the operand unchanged.

Equivalent - but only for positive operands: ff the left operand is positive, given that right operand is n, the result is the same as integer division by 2 ^ n.

Example 1:

00001000 >> 1 = 00000100

decimal version:

8 >> 1 = 4

Equivalent:

left_operand = 8
n = 1
2 ^ n = 2 ^ 1 = 2

ergo

left_operand / (2 ^ n) = 8 / (2 ^ 1) = 8 / 2 = 4

Example 2:

00010001 >> 3 = 00000010

decimal version:

17 >> 3 = 2

Equivalent:

left_operand = 17
n = 3
2 ^ n = 2 ^ 3 = 8

ergo

left_operand / (2 ^ n) = 17 / (2 ^ 3) = 17 / 8 = 2

Example 3:

11001111 >> 2 = 11110011

decimal version:

-49 >> 2 = -13

Equivalent is not working here:

left_operand = -49
n = 3
2 ^ n = 2 ^ 3 = 8

ergo

left_operand / (2 ^ n) = -49 / (2 ^ 3) = -49 / 8 = -6 != -13

Unsigned right shift (»>)

How does it look?

11111111 >>> 3

What does it do?

Acts as signed right shift. Shifts the bits in the left operand. It shifts them to the right. The only difference is that it is always replacing lost bits by 0, not by the value of the high-order bit.

How far?

By the number of places given on the right (in the right operand).

Effects

Low-order bits of the left operand (from its right-hand side) are removed (it is often being said: lost). Zeroes are shifted in from the left-hand side - no matter what is the sign of the left operand!

It is called zero extension - it treats the left operand as unsigned.

Decimal equivalent formula also works here:

11111111 >> 3 = 00011111

decimal version:

255 >> 3 = 31

Equivalent:

left_operand = 255
n = 3
2 ^ n = 2 ^ 3 = 8

ergo

left_operand / (2 ^ n) = 255 / (2 ^ 3) = 255 / 8 = 31