JavaScript: calcula la raíz n-ésima de un número

81

Estoy tratando de obtener la raíz enésima de un número usando JavaScript, pero no veo una forma de hacerlo usando el Math objeto . ¿Estoy pasando por alto algo?
Si no...

¿Existe una biblioteca matemática que pueda usar que tenga esta funcionalidad?
Si no...

¿Cuál es el mejor algoritmo para hacer esto yo mismo?

Nathan
fuente
¿Cuántas raíces quieres? ¿Solo el más obvio, o todos?
Ignacio Vazquez-Abrams

Respuestas:

146

¿Puedes usar algo como esto?

Math.pow(n, 1/root);

p.ej.

Math.pow(25, 1/2) == 5
Avión digital
fuente
1
Esto funcionará si la función pow puede tomar un exponente fraccionario. No estoy seguro, pero debería :)
Richard H
2
lo hace, pero no maneja números negativos
mplungjan
2
Una pequeña nota. La función pow se aproxima a la respuesta. Entonces, para valores grandes, esta aproximación puede devolver números muy incorrectos. [referencia ]. Lo mismo es cierto para la implementación de JS. ref
Debosmit Ray
2
¿Cómo se maneja Math.pow(-32, 1/5)?
Qian Chen
20

La nraíz de th xes la misma xque la potencia de 1/n. Simplemente puede usar Math.pow:

var original = 1000;
var fourthRoot = Math.pow(original, 1/4);
original == Math.pow(fourthRoot, 4); // (ignoring floating-point error)
Jeremy
fuente
1
¿Qué hay de Math.pow (-32, 1/5)?
Qian Chen
12

Utilice Math.pow ()

Tenga en cuenta que no maneja bien los negativos: aquí hay una discusión y un código que sí

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){}
}
mplungjan
fuente
8

Podrías usar

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

La nraíz -ésima de xes un número rtal que elevado ra la potencia de 1/nesx .

En números reales, hay algunas subcasas:

  • Hay dos soluciones (mismo valor con signo opuesto) cuando xes positivo y res par.
  • Hay una solución positiva cuando xes positiva y res impar.
  • Hay una solución negativa cuando xes negativa y res impar.
  • No hay solución cuando xes negativo y res par.

Dado que Math.powno le gusta una base negativa con un exponente no entero, puede usar

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

Ejemplos:

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)
Oriol
fuente
"nthRoot (-4, 2); // NaN (no hay solución)" bueno ... al menos no en números reales
Moritz
Después de ver stackoverflow.com/a/46268374/205696 encontré algunas optimizaciones para nthRoot. Dado que Math.pow(-4, 1/2)devuelve NaNy dado que solo necesitamos Math.absnúmeros negativos, podemos usar Math.abssolo números negativos e impares (no estoy seguro de que este último sea una optimización). Entonces en una línea:let nthRoot = (x, n) => n % 2 === 1 && x < 0 ? -(Math.abs(x) ** (1/n)) : x ** (1/n)
dotnetCarpenter
4

Para los casos especiales de raíz cuadrada y cúbica, es mejor usar las funciones nativas Math.sqrty Math.cbrtrespectivamente.

A partir de ES7, el operador de exponenciación** se puede utilizar para calcular la raíz n -ésima como la 1 / n- ésima potencia de una base no negativa:

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

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

Sin embargo, esto no funciona con bases negativas.

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

Aquí hay una función que intenta devolver el número imaginario. También comprueba primero algunas cosas comunes, por ejemplo: si obtiene la raíz cuadrada de 0 o 1, o si obtiene la raíz 0 del número x

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;
    }
SwiftNinjaPro
fuente
Utilice una declaración de cambio
Mattia S.
0

Bueno, sé que esta es una vieja pregunta. Pero, según la respuesta de SwiftNinjaPro, simplifiqué la función y solucioné algunos problemas de NaN. Nota: Esta función utilizó la característica ES6, la función de flecha y cadenas de plantillas, y exponenciación. Por lo tanto, es posible que no funcione en navegadores más antiguos:

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

Ejemplo:

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

Ejemplo (resultado numérico imaginario):

Math.numberRoot(-729, 6); // Returns a string containing "3i".
Zamy Arkre Nendmed
fuente