JavaScript: Обчислити n-й корінь числа


81

Я намагаюся отримати n-й корінь числа за допомогою JavaScript, але я не бачу способу зробити це за допомогою вбудованого Mathоб'єкта. Я щось пропускаю?
Якщо ні...

Чи існує математична бібліотека, якою я можу користуватися, яка має цю функціональність?
Якщо ні...

Який найкращий алгоритм зробити це сам?


Скільки коренів ти хочеш? Просто найочевидніший або всі вони?
Ігнасіо Васкес-Абрамс

Відповіді:


145

Чи можете ви використати щось подібне?

Math.pow(n, 1/root);

напр.

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

1
Це спрацює, якщо функція pow може приймати дробовий показник. Не впевнений, але повинен :)
Річард Х

2
він робить, але не обробляє від'ємні числа
mplungjan

1
Невелика примітка. Функція pow наближує відповідь. Отже, для великих значень це наближення може повернути дуже неправильні числа. [довідково ]. Те саме стосується реалізації JS. ref
Debosmit Ray

2
Як впоратися Math.pow(-32, 1/5)?
Цянь Чень,

20

nЙ корінь xтакий же , як xдо влади 1/n. Ви можете просто використовувати Math.pow:

var original = 1000;
var fourthRoot = Math.pow(original, 1/4);
original == Math.pow(fourthRoot, 4); // (ignoring floating-point error)

1
Як щодо Math.pow (-32, 1/5)?
Цянь Чень,

12

Використовуйте 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){}
}

8

Ви могли б використовувати

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

n-Й корінь xявляє собою число rтаке , що rзастосування сили 1/nце x.

У дійсних числах є кілька під-випадків:

  • Є два рішення (однакове значення з протилежним знаком), коли xпозитивне і 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)

"nthRoot (-4, 2); // NaN (рішення не існує)" ну ... принаймні не в реальних числах
Моріц

Побачивши stackoverflow.com/a/46268374/205696, я знайшов кілька оптимізацій для nthRoot. Оскільки Math.pow(-4, 1/2)повертається NaNі оскільки нам потрібні лише Math.absвід'ємні числа, ми можемо використовувати Math.absлише від'ємні та непарні числа (не впевнений, що останнє є оптимізацією). Отож одним рядком:let nthRoot = (x, n) => n % 2 === 1 && x < 0 ? -(Math.abs(x) ** (1/n)) : x ** (1/n)
dotnetCarpenter

4

Для особливих випадків квадратного та кубічного кореня найкраще використовувати власні функції Math.sqrtта Math.cbrtвідповідно.

Починаючи з ES7, оператор** степенізації може бути використаний для обчислення 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

0

Ось функція, яка намагається повернути уявне число. Він також спочатку перевіряє кілька загальних речей, наприклад: якщо отримуємо квадратний корінь 0 або 1, або отримуємо 0-й корінь числа 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;
    }

Будь ласка, використовуйте заяву про перемикання
Mattia S.

0

Ну, я знаю, це старе питання. Але, виходячи з відповіді SwiftNinjaPro, я спростив цю функцію та виправив деякі проблеми з NaN. Примітка: Ця функція використовувала функцію ES6, функцію стрілки та рядки шаблонів, а також експоненцію. Отже, це може не працювати в старих браузерах:

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

Приклад (результат уявного числа):

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

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.