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.

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.