JavaScript:计算数字的第n个根

时间:2011-09-05 13:14:06

标签: algorithm math javascript

我正在尝试使用JavaScript获取数字的第n个根,但我没有看到使用内置Math对象的方法。我忽略了什么吗? 如果不是......

我是否可以使用具有此功能的数学库?
如果不是......

自己做这个的最佳算法是什么?

9 个答案:

答案 0 :(得分:114)

你能用这样的东西吗?

Math.pow(n, 1/root);

例如

Math.pow(25, 1/2) == 5

答案 1 :(得分:19)

n的{​​{1}}根与x的{​​{1}}相同。x。您只需使用1/n

即可
Math.pow

答案 2 :(得分:10)

使用Math.pow()

请注意,它不能很好地处理否定 - 这是一个讨论和一些代码

http://cwestblog.com/2011/05/06/cube-root-an-beyond/

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){}
}

答案 3 :(得分:5)

您可以使用

Math.nthroot = function(x,n) {
    //if x is negative function returns NaN
    return this.exp((1/n)*this.log(x));
}
//call using Math.nthroot();

答案 4 :(得分:3)

n x的根r是一个r1/n x的力量为x。< / p>

实际上,有一些子句:

  • r为正数且x为偶数时,有两种解决方案(符号相反的值相同)。
  • r为正数且x为奇数时,有一个正解。
  • r为负数且x为奇数时,有一个否定解决方案。
  • r为否定且Math.pow为偶数时,没有解决方案。

由于function nthRoot(x, n) { if(x < 0 && n%2 != 1) return NaN; // Not well defined return (x < 0 ? -1 : 1) * Math.pow(Math.abs(x), 1/n); } 不喜欢带有非整数指数的负基数,因此可以使用

nthRoot(+4, 2); // 2 (the positive is chosen, but -2 is a solution too)
nthRoot(+8, 3); // 2 (this is the only solution)
nthRoot(-8, 3); // -2 (this is the only solution)
nthRoot(-4, 2); // NaN (there is no solution)

示例:

#!/bin/bash
mkdir ~/Desktop/ror_save_unlock_all

echo "This script takes ~/Library/Application Support/com.riskofrain.riskofrain/Save.ini and backs it up to ~/Desktop/ror_save_unlock_all/originalSave. It generates a new Save.ini that is built to your specifications, unlocking all items and achievements or just the ones you choose, and replaces the existing Save.ini with the new one." >> ~/Desktop/ror_save_unlock_all/README.txt

mkdir ~/Desktop/ror_save_unlock_all/originalSave

cp ~/Library/Application\ Support/com.riskofrain.riskofrain/Save.ini ~/Desktop/ror_save_unlock_all/originalSave/

cd ~/Desktop/ror_save_unlock_all

echo -n 'How would you like the new Save.ini to be built? Press 1 for all unlocks or 2 to customize.'
read text
if [ $text = "1" ]
then 
    {
        echo "[Achievement]" >> EOF1

        count=1

        while [ $count -lt 55 ]
        do
          echo "acheivement${count}=\"2\"" >> EOF2
          count=`expr $count + 1`
        done

        echo "[Record]" >> EOF3

        count=1

        while [ $count -lt 31 ]
        do
          echo "mons${count}=\"1\"" >> EOF4
          count=`expr $count + 1`
        done

        count=1

        while [ $count -lt 110 ]
        do
          echo "item${count}=\"1\"" >> EOF5
          count=`expr $count + 1`
        done

        count=1

        while [ $count -lt 10 ]
        do
          echo "artifact${count}=\"1\"" >> EOF6
          count=`expr $count + 1`
        done

        cat EOF1 EOF2 EOF3 EOF4 EOF5 EOF6 > Save.ini 

        rm EOF1 EOF2 EOF3 EOF4 EOF5 EOF6 

        cp -force ~/Desktop/ror_save_unlock_all/Save.ini ~/Library/Application\ Support/com.riskofrain.riskofrain/Save.ini

        echo "Original Save.ini successfully overwritten."

        exit

    }   

elif [ $text = "2" ]; then
    {
        echo "You selected customize. Now we will build a custom Save.ini"
        echo -n "Press 1 if you want to unlock all achievements, press 2 to continue without unlocking all achievements."
        read text
        if [ $text = "1" ]; then 

            {
                echo "[Achievement]" >> EOF1
                count=1
                while [ $count -lt 55 ]
                do
                  echo "acheivement${count}=\"2\"" >> EOF2
                  count=`expr $count + 1`
                done

                echo "All achievements successfully unlocked."
                echo -n "Press 1 to make the Save.ini and replace the existing one with it and then exit, or press 2 to customize it further."
                read text
                if [ $text = "1" ]; then
                    {
                        cat EOF1 EOF2 > Save.ini
                        rm EOF1 EOF2
                        cp -force ~/Desktop/ror_save_unlock_all/Save.ini ~/Library/Application\ Support/com.riskofrain.riskofrain/Save.ini
                        echo "Original Save.ini successfully overwritten."
                        exit
                    }

                elif [ $text = "2" ] then;
                    {
                        echo -n "Press 1 to unlock all monster logs, or press 2 to continue without unlocking all monster logs."
                        read text
                        if [ $text = "1" ]; then
                            {
                                echo "[Record]" >> EOF3 

                                count=1
                                while [ $count -lt 31 ]
                                do
                                  echo "mons${count}=\"1\"" >> EOF4
                                  count=`expr $count + 1`
                                done

                                echo "All achievements successfully unlocked."
                                echo -n "Press 1 to make the Save.ini and replace the existing one with it and then exit, or press 2 to customize it further."
                                read text
                            }
                        }
                    }
                }

答案 5 :(得分:3)

对于square和cubic root的特殊情况,最好分别使用本机函数Math.sqrtMath.cbrt

从ES7开始,exponentiation operator **可用于计算 n 根作为 1 / n 非负基数的力量:

let root1 = Math.PI ** (1 / 3); // cube root of π

let root2 = 81 ** 0.25;         // 4th root of 81

但这不适用于负面基础。

let root3 = (-32) ** 5;         // NaN

答案 6 :(得分:0)

这是一个试图返回虚数的函数。它还首先检查一些常见的事物,例如:获得0或1的平方根,还是获得x的第0个根。

function root(x, n){
        if(x == 1){
          return 1;
        }else if(x == 0 && n > 0){
          return 0;
        }else if(x == 0 && n < 0){
          return Infinity;
        }else if(n == 1){
          return x;
        }else if(n == 0 && x > 1){
          return Infinity;
        }else if(n == 0 && x == 1){
          return 1;
        }else if(n == 0 && x < 1 && x > -1){
          return 0;
        }else if(n == 0){
          return NaN;
        }
        var result = false;
        var num = x;
        var neg = false;
        if(num < 0){
            //not using Math.abs because I need the function to remember if the number was positive or negative
            num = num*-1;
            neg = true;
        }
        if(n == 2){
            //better to use square root if we can
            result = Math.sqrt(num);
        }else if(n == 3){
            //better to use cube root if we can
            result = Math.cbrt(num);
        }else if(n > 3){
            //the method Digital Plane suggested
            result = Math.pow(num, 1/n);
        }else if(n < 0){
            //the method Digital Plane suggested
            result = Math.pow(num, 1/n);
        }
        if(neg && n == 2){
            //if square root, you can just add the imaginary number "i=√-1" to a string answer
            //you should check if the functions return value contains i, before continuing any calculations
            result += 'i';
        }else if(neg && n % 2 !== 0 && n > 0){
            //if the nth root is an odd number, you don't get an imaginary number
            //neg*neg=pos, but neg*neg*neg=neg
            //so you can simply make an odd nth root of a negative number, a negative number
            result = result*-1;
        }else if(neg){
            //if the nth root is an even number that is not 2, things get more complex
            //if someone wants to calculate this further, they can
            //i'm just going to stop at *n√-1 (times the nth root of -1)
            //you should also check if the functions return value contains * or √, before continuing any calculations
            result += '*'+n+√+'-1';
        }
        return result;
    }

答案 7 :(得分:0)

嗯,我知道这是一个老问题。但是,基于SwiftNinjaPro的答案,我简化了功能并修复了一些NaN问题。注意:此函数使用了ES6功能,箭头函数和模板字符串以及指数。因此,它可能在较旧的浏览器中不起作用:

df2.head()

   col1          col2
0  NM_000000_foo bar
1  NM_000001     foo

示例:

Math.numberRoot = (x, n) => {
  return (((x > 1 || x < -1) && n == 0) ? Infinity : ((x > 0 || x < 0) && n == 0) ? 1 : (x < 0 && n % 2 == 0) ? `${((x < 0 ? -x : x) ** (1 / n))}${"i"}` : (n == 3 && x < 0) ? -Math.cbrt(-x) : (x < 0) ? -((x < 0 ? -x : x) ** (1 / n)) : (n == 3 && x > 0 ? Math.cbrt(x) : (x < 0 ? -x : x) ** (1 / n)));
};

示例(虚数结果):

Math.numberRoot(-64, 3); // Returns -4

答案 8 :(得分:0)

我已经写了一个算法,但是当您需要很多数字时,它会很慢:

https://github.com/am-trouzine/Arithmetic-algorithms-in-different-numeral-systems

NRoot(orginal, nthRoot, base, numbersAfterPoint);

该函数返回一个字符串。

例如

var original = 1000;
var fourthRoot = NRoot(original, 4, 10, 32);
console.log(fourthRoot); 
//5.62341325190349080394951039776481