Bit Manipulation · 9 of 10
Calculate square of a number without using multiplication, division and pow()
Find n times n using only adding and doubling, by splitting n into powers of two like 8 + 4 + 1.
- Simple way
- time O(n)
room O(1) - Clever way
- time O(log n)
room O(1)
The problem, simply
You get a whole number n. Give back n * n, the square of n.
The catch: you may not use the times sign *, the divide sign /, or Math.pow. You may add, subtract and use the bit tools, like shifting bits left and right. The number can be negative, and a square is never negative.
A story to remember it
Picture it
13 is 1101 in bits, so 13 = 8 + 4 + 1. Shifting 13 left by 0, 2 and 3 places gives 13, 52 and 104. Adding those three piles gives 169.
- looking now
- answer
Examples
A normal number
- In
n = 5- Out
25
5 is 101 in bits, so 5 = 4 + 1. The piles are 5 and 20, and 5 + 20 = 25.
A negative number
- In
n = -3- Out
9
A minus times a minus is a plus. Turn -3 into 3 first, then square it.
A power of two
- In
n = 8- Out
64
8 is 1000 in bits. Only one bit is on, so the answer is one pile: 8 shifted left 3 places, which is 64.
Zero
- In
n = 0- Out
0
No bits are on, so no pile is added. The loop never runs and the answer is 0.
Way 1: the simple way
Times is only adding again and again. 5 times 5 is 5 + 5 + 5 + 5 + 5.
- Make
npositive, because the square of-nis the same as the square ofn. - Start a total at 0.
- Add
nto the total,ntimes.
class Solution {
public static long square(int n) {
long num = Math.abs((long) n); // make it positive, in a long so it cannot overflow
long total = 0;
for (long i = 0; i < num; i++) {
total += num; // add n, n times
}
return total;
}
}How long it takes: the loop runs n times, O(n). For n near 46,000 that is 46,000 adds for one answer. Extra room: one total, O(1).
Way 2: the clever way
Look at the bits of n. Every bit that is on stands for a power of two inside n. Shifting a number left by i places is the same as doubling it i times. So we keep a pile that doubles each round, and add the pile to the total only when the matching bit of n is on.
- Make
npositive. Letpile = nandtotal = 0. - While
nstill has bits: if the lowest bit is 1, addpiletototal. - Double the pile with
pile << 1. Drop the lowest bit ofnwithn >> 1. - When
nreaches 0,totalis the square.
Square 13 with doubling piles
01 / 09
We want 13 times 13 with no times sign. In bits 13 is 1101, which means 13 = 8 + 4 + 1. The pile starts as one copy of 13. The total starts at 0.
- total
- 0
- looking now
- checking
- done
- answer
- rejected
- just added
class Solution {
public static long square(int n) {
long bits = Math.abs((long) n); // whose bits we read
long pile = bits; // n times 1, then n times 2, 4, 8, ...
long total = 0;
while (bits > 0) {
if ((bits & 1) == 1) {
total += pile; // this power of two is inside n
}
pile <<= 1; // double the pile
bits >>= 1; // look at the next bit
}
return total;
}
}How long it takes: one round per bit of n, and n has about log n bits, O(log n). For any int that is at most 31 rounds. Extra room: three numbers, O(1).
Another way: cut it in half
There is a neat rule. Let h = n >> 1, which is n / 2 rounded down.
- If
nis even,n = 2h, son * n = 4 * h * h. - If
nis odd,n = 2h + 1, son * n = 4 * h * h + 4 * h + 1.
Times 4 is a left shift by 2. So we square the half, shift, and add a little. Each call cuts n in half.
class Solution {
public static long square(long n) {
if (n < 0) n = -n;
if (n == 0) return 0;
long h = n >> 1; // half of n, rounded down
long s = square(h); // h * h
if ((n & 1) == 0) return s << 2; // even: 4 * h * h
return (s << 2) + (h << 2) + 1; // odd: 4 * h * h + 4 * h + 1
}
}This is also O(log n) time, but the waiting calls need O(log n) room on the call stack.
Watch out for
Math.abs(Integer.MIN_VALUE)is still negative inint. Cast tolongbefore taking the absolute value.- Do not forget negative inputs. If you skip
Math.abs, the testbits > 0is false right away and you return 0 for-3. - Zero must return 0. Both ways handle it because the loop never starts.
What interviewers ask next
- Multiply two different numbers
aandbthe same way? Yes. Read the bits ofband add shifted copies ofa. This is called Russian peasant multiplication, and it is how simple chips multiply. - Can you square with only adding odd numbers? Yes.
1 + 3 + 5 + ... + (2n - 1)equalsn * n. Keep a running odd number and add 2 to it each step. That isO(n). - What if the answer does not fit in a
long? UseBigInteger, or return the answer modulo a big prime, adding and reducing at each step. - Why is the shift loop faster? It does work per bit, not per unit. 1,000,000 has only 20 bits, so 20 rounds instead of a million adds.
Remember this
Grown-up words: the piles are partial products, doubling is a left shift, dropping the last bit is a right shift, and the whole method is shift and add multiplication, also called Russian peasant multiplication.