Occasionally, we’re faced with the problem of calculating the square root of an integer. Here are three algorithms:
- This method is the least efficient. It relies on the fact that the difference between consequent squares is the series of odd numbers.
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
sqr(i) | 0 | 1 | 4 | 9 | 16 | 25 | 36 |
sqr(i) – sqr(i + 1) | 1 | 3 | 5 | 7 | 9 | 11 | … |
So, given an input integer n
what the algorithm does is:
It starts with square = 1
and keeps adding odd integers (delta
) from the series until square
reaches n
(the input integer). The root is sqrt(n) = delta / 2 - 1
.
Implementation in C++
template type sqrt(type n) { type square = 1; type delta = 3; while (square square += delta; delta += 2; } return delta / 2 - 1; }
- The second method to guesses a root (
guess
) and then tries to minimize the distance to the real root.
In C++:
template type sqrt(type n) { type upperBound = n + 1; type guess = 0; type lowerBound = 0; type delta; while (delta = (guess = (upperBound + lowerBound) / 2) * guess - n) if (delta > 0) upperBound = guess; else lowerBound = guess; return guess; }
- This method is similar to the previous. However, it has different logic. We’re trying to “build” the root bit-by-bit. It is the most efficient among them.
In C++:
template type sqrt(type n) { type guess = 0; int newBit = 1 << (sizeof(type) * 4 - 1); while (newBit > 0) { if (n >= (guess + newBit) * (guess + newBit)) guess += newBit; newBit >>= 1; } return guess; }
Caution!
- C++’s
<cmath>
is faster! - Results for non-integer squares are not reliable.