JavaScript: Tính căn thứ n của một số


80

Tôi đang cố gắng lấy gốc thứ n của một số bằng JavaScript, nhưng tôi không thấy cách nào để thực hiện bằng cách sử dụng Mathđối tượng được tích hợp sẵn . Tôi có đang bỏ qua thứ gì đó không?
Nếu không...

Có thư viện toán học nào tôi có thể sử dụng có chức năng này không?
Nếu không...

Thuật toán tốt nhất để tự làm điều này là gì?


Bạn muốn có bao nhiêu rễ? Chỉ một cái rõ ràng nhất, hay tất cả chúng?
Ignacio Vazquez-Abrams

Câu trả lời:


144

Bạn có thể sử dụng một cái gì đó như thế này?

Math.pow(n, 1/root);

ví dụ.

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

1
Điều này sẽ hoạt động nếu hàm pow có thể nhận theo số mũ phân số. Không chắc, nhưng nó nên :)
Richard H

2
nó nhưng không xử lý số âm
mplungjan

1
Một lưu ý nhỏ. Hàm pow ước tính câu trả lời. Vì vậy, đối với các giá trị lớn, giá trị gần đúng này có thể trả về số rất sai. [tham khảo ]. Điều này cũng đúng với việc triển khai JS. ref
Debosmit Ray

2
Cách xử lý Math.pow(-32, 1/5)?
Qian Chen

20

Các ngốc thứ của xcũng giống như xvới sức mạnh của 1/n. Bạn chỉ cần sử dụng Math.pow:

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

1
Còn Math.pow (-32, 1/5) thì sao?
Qian Chen

12

Sử dụng Math.pow ()

Lưu ý rằng nó không xử lý tiêu cực một cách độc đáo - đây là một cuộc thảo luận và một số mã

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

Bạn đã có thể sử dụng

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

Các ngốc -thứ của xlà một số rví dụ rằng rvới sức mạnh của 1/nx.

Trong số thực, có một số trường hợp con:

  • Có hai nghiệm (cùng giá trị, trái dấu) khi nào xlà dương và rlà nghiệm chẵn.
  • Có một nghiệm dương khi xlà tích cực và rlà nghiệm lẻ.
  • Có một nghiệm âm khi xlà âm và rlà nghiệm lẻ.
  • Không có giải pháp khi nào xlà tiêu cực và rlà thậm chí.

Math.powkhông thích cơ số âm với số mũ không phải số nguyên, bạn có thể sử dụng

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

Ví dụ:

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 (không có lời giải)" thì ... ít nhất không phải ở dạng số thực
Moritz

Sau khi xem stackoverflow.com/a/46268374/205696, tôi đã tìm thấy một vài cách tối ưu hóa nthRoot. Vì Math.pow(-4, 1/2)trả về NaNvà vì chúng ta chỉ cần Math.abssố âm, nên chúng ta chỉ có thể sử dụng Math.abscho số âm số lẻ (không chắc cái sau là tối ưu hóa). Vì vậy, trong một dòng:let nthRoot = (x, n) => n % 2 === 1 && x < 0 ? -(Math.abs(x) ** (1/n)) : x ** (1/n)
dotnetCarpenter

4

Đối với các trường hợp đặc biệt của căn bậc hai và bậc ba, tốt nhất là sử dụng các hàm gốc Math.sqrtMath.cbrttương ứng.

Kể từ ES7, toán tử lũy thừa** có thể được sử dụng để tính căn thứ nlũy thừa thứ 1 / n của cơ số không âm:

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

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

Tuy nhiên, điều này không hoạt động với các cơ sở phủ định.

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

0

Đây là một hàm cố gắng trả về số ảo. Nó cũng kiểm tra một số điểm chung trước tiên, ví dụ: nếu nhận căn bậc hai của 0 hoặc 1 hoặc nhận căn bậc 0 của số 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;
    }

Vui lòng sử dụng câu lệnh chuyển đổi
Mattia S.

0

Vâng, tôi biết đây là một câu hỏi cũ. Tuy nhiên, dựa trên câu trả lời của SwiftNinjaPro, tôi đã đơn giản hóa chức năng và khắc phục một số sự cố NaN. Lưu ý: Hàm này sử dụng tính năng ES6, hàm mũi tên và chuỗi mẫu, và phép tính lũy thừa. Vì vậy, nó có thể không hoạt động trong các trình duyệt cũ hơn:

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

Thí dụ:

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

Ví dụ (Kết quả số ảo):

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.