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.

Categories: BlogJavaScriptMath

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.

Leave a Reply

Your email address will not be published. Required fields are marked *