It's pretty common to use the Newton-Raphson method to compute the square root of a number. Recently I had to use this method to solve a different equation at work, but it's also good for solving the square root problem.
Basically you frame the question in terms of a function that equals zero. If you want to find the square root X of number N, thenX2 = N. Expressed as a zero-value equation, that is
The Newton-Raphson method starts with an initial guess, and then iterates through a loop, altering the guess until the current guess is really close to the previous guess. Each time through the loop, the new guess G is computed by subtracting F/F' from the old guess X. F and F' are the function above and its derivative. The derivative of this particular function is:
So each time through the loop, we compute the new guess as follows:
or
G = X - 0.5*X + 0.5*N/X
or
G = 0.5*(X + N/X)
So the only thing left is what to use as your initial guess. Ideally you'd want to pick something that's pretty close to the final answer because otherwise for some functions, you might get the wrong result. However for this particular application, the function has only one positive solution, so there's no real danger if you simply start with the input number N as your initial guess.
mob/verb/square_root(n as num)
var/nval = abs(n)
var/x = 0
var/g = nval
var/tolerance = 0.00001
var/nloop = 0
// The loop should converge quickly. If it doesn't, maybe our
// tolerance is too small.
while (abs(g - x) > tolerance && nloop < 1000)
x = g
g = 0.5 * (x + nval/x)
nloop++
src << "The square root of [n] is roughly [g][n < 0 ? "i" : ""]"
#ifdef DEBUG
src << "We were off by [sqrt(nval) - g] after [nloop] iterations"
#endif
If you already new this, then I am an idiot and should eat a pastrie of worms.