Binary Shifts
You already know a slick trick in our everyday base-ten numbers: to multiply by
10, just stick a 0 on the right.
34 becomes 340; every digit slides one
column to the left, into a column worth ten times as much. To divide by
10, slide everything one column to the right and
rub off whatever falls off the end.
Binary has exactly the same trick — but because each
place value
is worth twice the one to its right (ones, twos, fours, eights…), sliding the bits
along multiplies or divides by 2, not 10. Sliding all
the bits sideways is called a binary shift, and it is one of the fastest things a
computer can do.
Shift left = multiply by 2
Take the 8-bit number 00000110. Reading the
place values, that's 4 + 2 = 6. Now shift every bit one place to the
left and drop a fresh 0 into the empty space on the
right:
Every 1 has moved into a column worth double, so the number doubles:
00000110 (6) becomes
00001100 (12). That extra
0 on the right is the exact mirror of adding a
0 to multiply by ten in denary.
Shift right = divide by 2
Going the other way, shift every bit one place to the right. Each
1 drops into a column worth half as much, so the number halves. Start
with 00001100 (12):
We get 00000110 (6) — a clean halving. But
watch what happens with an odd number like
00001101 (13): the rightmost
1 falls off the end and is gone for good, leaving
00000110 (6). The computer has done
13 \div 2 = 6 remainder 1 — and
simply thrown the remainder away. A right shift always rounds down.
Shifting by n places
One shift multiplies or divides by 2. Do it n
times in a row and each factor of 2 stacks up, so shifting by
n places multiplies or divides by 2^n:
\text{left by } n:\; x \times 2^n \qquad\qquad \text{right by } n:\; \lfloor x \div 2^n \rfloor
So a left shift of 3 multiplies by
2^3 = 8, and a right shift of 2 divides by
2^2 = 4 (rounding down). In code these are written with the
<< ("shift left") and >> ("shift right") operators.
- Shifting all bits left by n places multiplies the number by 2^n.
- Shifting all bits right by n places divides the number by 2^n, discarding any remainder (rounding down).
- Empty places opening up are filled with 0; bits pushed off the end are lost.
Try it yourself — shift and Run
This program takes a starting number and shifts it. Change start and places,
try both << and >>, and press Run. Notice how
the answer is always the number multiplied or divided by a power of 2.
const start: number = 6;
const places: number = 1;
const left: number = start << places; // shift left → multiply by 2^places
const right: number = start >> places; // shift right → divide by 2^places
console.log(start + " << " + places + " = " + left + " (× " + (2 ** places) + ")");
console.log(start + " >> " + places + " = " + right + " (÷ " + (2 ** places) + ", rounded down)");
You can even see the bits move. This version prints the 8-bit pattern
before and after a left shift:
const start: number = 13; // 00001101
const shifted: number = start << 1; // shift left by 1
const bits = (n: number): string => (n & 0xff).toString(2).padStart(8, "0");
console.log("before: " + bits(start) + " = " + start);
console.log("after : " + bits(shifted) + " = " + shifted);
Multiplication is real work for a processor, but sliding bits sideways is almost free — it's one of
the very fastest operations there is. So when a program needs to multiply or divide by a power of
2 (which happens constantly — think of splitting a screen into halves and
quarters, or stepping through memory), it often shifts instead. Compilers even spot
x \times 8 in your code and quietly turn it into
x << 3 for you.
Bits pushed off the end of the register are lost forever — a shift doesn't
"remember" them.
On a 8-bit number a left shift can
overflow: shift 10000000 (128)
left by one and the top 1 is shoved off the left end, leaving
00000000 — you get 0, not
256, because 256 won't fit in
8 bits.
A right shift throws away whatever falls off the right end — the remainder. That's
why right-shift division always rounds down: 7 \gg 1 = 3
(not 3.5), because the leftover 1 is simply
discarded. Shift right far enough and everything drops off, leaving 0.