Lately, I have been in a math oriented mood. Yesterday, I was thinking about how the fact that you can take the square root of a number in JavaScript, but not the cube root, 4th root, etc.. Naturally, I looked to Wikipedia to find the algorithm to find the nth root of a number. I developed the following unnecessary function:
function bad_nthroot(x, n) {
// If an error occurs, don't return anything.
try {
// If an error occurs
// Loop through the nth root algorithm until no difference is found.
var x2, A = x, n1 = n - 1, itersLeft = 99;
do {
x2 = x;
x = (n1 * x2 + A / Math.pow(x2, n1)) / n;
} while(x != x2 && itersLeft--);
// If less than 100 iterations were done or if the difference between the
// previous approximation and the current one is acceptable, return the
// current one.
if((itersLeft || (Math.abs(x - x2) < 1 && (x < 0) == (x2 < 0))) && isFinite(x))
return x;
} catch(e){}
}
After testing out the function a bit and taking a look at an online example, I realized that I could have done it with the Math.pow()
. After all, the cube root of a number is the same thing as that number to the power of 1/3. With this in mind, I redeveloped the function and came up with the following, more accurate function:
function nthroot(x, n) {
try {
var negate = n % 2 == 1 && x < 0;
if(negate)
x = -x;
var possible = Math.pow(x, 1 / n);
n = Math.pow(possible, n);
if(Math.abs(x - n) < 1 && (x > 0 == n > 0))
return negate ? -possible : possible;
} catch(e){}
}
One notable difference is the fact that calling bad_nthroot(8, 1/2)
results in 63.99999999999999. On the other hand, nthroot(8, 1/2)
results in 64. There are many other differences as well.
The reason I created this function instead of using Math.pow(x, 1 / n)
is because of examples such as Math.pow(-8, 1 / 3)
. Even though the cube root of -8 is -2, Math.pow(-8, 1 / 3)
results in NaN. On the other hand, nthroot(-8, 3)
results in the expected value of -2
.
If you find something wrong with my nthroot function, please let me know.
8 Comments
DaveRandom · September 13, 2011 at 7:24 AM
FYI the square root of -8 is NOT -2. -2 squared is 8. It is debatable as to whether negative numbers have square roots, but personally I feel the NaN is not an unreasonable output.
If you wanted to get roots on negative numbers in this fashion you could test whether x < 0, if it is multiply it by -1, do the calculation, then convert back to negative for the return value…
pegasus · April 5, 2019 at 1:34 PM
-2 squared is 4, not 8. -2 *cubed* is -8.
cwest · September 19, 2011 at 5:24 PM
@DaveRandom you definitely misread my article. First of all, the main point of this article is to provide a way to find the CUBE root (3) and beyond of numbers. Second, I took the cube root of -8 which is indeed -2. I do appreciate you reading my article, but I ask that you read it carefully before stating that I made a mistake. 8)
ildar · March 12, 2012 at 7:55 PM
the nthroot function is too verbose. Moreover this implementation has two launches of the Math.pow method that is very expensive. Many time ago I decided to myself that cubic root should be estimated as below:
Math.sign = function(x)
{
return x === 0 ? 0 : x > 0 ? +1 : -1;
};
Math.cubt = function(x)
{
return Math.sign(x) * Math.pow(Math.abs(x), 1 / 3);
};
Even this implementation waits to be optimized.
Connor · March 31, 2012 at 1:17 AM
“FYI the square root of -8 is NOT -2. -2 squared is 8. It is debatable as to whether negative numbers have square roots”
-2 squared is 8? lol
and there CAN be negative square roots but it just gets into the use of “i” or the imaginary number (negative root 1).
Chris West · April 2, 2012 at 10:22 AM
I am not sure why so many people are confused about the purpose of this article. The purpose is to determine the cube root (third root) of a number. I realize that the square root of -8 is not -2. Interestingly enough, nowhere in my article do I assert that.
MathIsHard · April 26, 2017 at 8:59 PM
“I realize that the square root of -8 is not -2”. I feel your pain 🙂
Charlie · June 4, 2012 at 11:58 PM
Hi, Chris:
I am first time come to this web site. Your converter program works very well. Except it can not convert my 12 digits of UPC code into ” 7.1586E+11″ format, can you help ? Thanks very much.