Próbuję uzyskać n-ty pierwiastek liczby za pomocą JavaScript, ale nie widzę sposobu, aby to zrobić za pomocą wbudowanego Math
obiektu. Czy coś przeoczę?
Jeśli nie...
Czy istnieje biblioteka matematyczna, której mogę użyć, i która ma taką funkcję?
Jeśli nie...
Jaki jest najlepszy algorytm, aby zrobić to sam?
algorithm
math
javascript
Nathan
źródło
źródło
Odpowiedzi:
Czy możesz użyć czegoś takiego?
Math.pow(n, 1/root);
na przykład.
Math.pow(25, 1/2) == 5
źródło
Math.pow(-32, 1/5)
?n
Korzeń thx
jest taka sama jakx
do potęgi1/n
. Możesz po prostu użyćMath.pow
:var original = 1000; var fourthRoot = Math.pow(original, 1/4); original == Math.pow(fourthRoot, 4); // (ignoring floating-point error)
źródło
Użyj Math.pow ()
Zauważ, że nie radzi sobie dobrze z negatywami - tutaj jest dyskusja i trochę kodu, który to robi
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){} }
źródło
Możesz użyć
Math.nthroot = function(x,n) { //if x is negative function returns NaN return this.exp((1/n)*this.log(x)); } //call using Math.nthroot();
źródło
n
-Ty pierwiastekx
jest liczbąr
takie, żer
do potęgi1/n
jestx
.W liczbach rzeczywistych jest kilka przypadków podrzędnych:
x
jest dodatnia ir
parzysta.x
jest pozytywne ir
dziwne.x
jest ujemne ir
jest dziwne.x
jest ujemne ir
równe.Ponieważ
Math.pow
nie lubi ujemnej podstawy z wykładnikiem niecałkowitym, możesz użyć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); }
Przykłady:
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)
źródło
nthRoot
. PonieważMath.pow(-4, 1/2)
zwracaNaN
i ponieważ potrzebujemy tylkoMath.abs
liczb ujemnych, możemy używaćMath.abs
tylko liczb ujemnych i nieparzystych (nie jestem pewien, czy ta ostatnia jest optymalizacją). A więc w jednej linii:let nthRoot = (x, n) => n % 2 === 1 && x < 0 ? -(Math.abs(x) ** (1/n)) : x ** (1/n)
W szczególnych przypadkach pierwiastka kwadratowego i sześciennego najlepiej jest używać odpowiednio natywnych funkcji
Math.sqrt
iMath.cbrt
.Począwszy od ES7, operator potęgowania
**
może być użyty do obliczenia n- tego pierwiastka jako 1 / n- tej potęgi nieujemnej podstawy:let root1 = Math.PI ** (1 / 3); // cube root of π let root2 = 81 ** 0.25; // 4th root of 81
Nie działa to jednak w przypadku zasad ujemnych.
let root3 = (-32) ** 5; // NaN
źródło
Oto funkcja, która próbuje zwrócić liczbę urojoną. Najpierw sprawdza również kilka typowych rzeczy, na przykład: czy uzyskuje się pierwiastek kwadratowy z 0 lub 1 lub uzyskuje się zerowy pierwiastek z liczby 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; }
źródło
Wiem, że to stare pytanie. Ale w oparciu o odpowiedź SwiftNinjaPro uprościłem funkcję i naprawiłem kilka problemów z NaN. Uwaga: Ta funkcja wykorzystywała funkcję ES6, funkcję strzałki i ciągi szablonów oraz potęgę. Może więc nie działać w starszych przeglądarkach:
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))); };
Przykład:
Math.numberRoot(-64, 3); // Returns -4
Przykład (wynik liczby urojonej):
Math.numberRoot(-729, 6); // Returns a string containing "3i".
źródło
Napisałem algorytm, ale jest powolny, gdy potrzebujesz wielu liczb po punkcie:
https://github.com/am-trouzine/Arithmetic-algorithms-in-different-numeral-systems
Funkcja zwraca ciąg.
Na przykład
var original = 1000; var fourthRoot = NRoot(original, 4, 10, 32); console.log(fourthRoot); //5.62341325190349080394951039776481
źródło