Sqrt(x)
I came across a fun exercise on LeetCode, where you have to calculate f(x)=√x, without using the standard library functions such as Math.Pow
or x**0.5
. Wikipedia has plenty of implementations to solve this problem efficiently, but I figured it would be a nice challenge to come up with a solution of my own.
My approach was to determine a upper and a lower bound, and do a binary search to find the solution. Let L be the lower bound. Since we know that a square root function requires that x>0, we can set L=0. Likewise, let U be the upper bound. We know that √x<x (if x>1), which we use to define the upper bound U=max(1,x).
Now we are going to guess what √x is. We know that √x lies between L<√x<U. Let k be our guess and initially set this to k=L+U2.
Next we calculate the error of our guess, which we can do with | √x−k |≤ϵ. However, because we cannot calculate square root functions, we need to square it and compare k2 with x, giving | x−k2 |≤ϵ.
While the error is bigger than ϵ, we need to adjust our guess. We do this by comparing k2 to x.
- If x<k2 then we adjust the upper bound and set it to U=k.
- If x>k2 then we adjust the lower bound and set it to L=k.
public class Solution {
public int MySqrt(int x) {
double lowerBound = 0;
double upperBound = Math.Max(1, x);
double guess = (upperBound + lowerBound) / 2;
double epsilon = 0.1;
while (Math.Abs(guess * guess - x) > epsilon || guess * guess < x) {
double guess2 = guess * guess;
if (x < guess2) {
upperBound = guess;
}
if (x > guess2) {
lowerBound = guess;
}
guess = (upperBound + lowerBound) / 2;
}
return (int)guess;
}
}
The extra check guess * guess < x
ensures that we are always over estimating x and getting the correct answer after truncating the output.