Skip to content

Commit 236d38d

Browse files
authored
Merge pull request #72 from pugulist/codex/improve-newton_raphson.js-function
2 parents 194e26f + cec55a1 commit 236d38d

File tree

1 file changed

+33
-5
lines changed

1 file changed

+33
-5
lines changed

math_modules/newton_raphson.js

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,39 @@
22

33
/*global module:true*/
44

5-
// Calculating nth root of 'a'
5+
// Calculate the nth root of `a` using the Newton–Raphson method.
6+
//
7+
// The function returns a string representing the result rounded to six
8+
// significant digits to preserve the behaviour expected by callers of the
9+
// previous implementation.
610
let nthRoot = (n, a) => {
7-
if (n === 2)
11+
// Basic validation – n must be a positive integer.
12+
if (!Number.isInteger(n) || n <= 0) {
13+
return NaN;
14+
}
15+
16+
// Special cases for zero and common roots.
17+
if (a === 0) {
18+
return '0';
19+
}
20+
if (n === 2) {
821
return Math.sqrt(a).toPrecision(6);
9-
else if (n === 3)
22+
} else if (n === 3) {
1023
return Math.cbrt(a).toPrecision(6);
24+
}
25+
26+
// Even roots of negative numbers do not have a real solution.
27+
if (a < 0 && n % 2 === 0) {
28+
return NaN;
29+
}
30+
31+
// Keep track of the sign so that odd roots of negative numbers are handled
32+
// correctly while the iterative algorithm works on a positive value.
33+
let sign = 1;
34+
if (a < 0) {
35+
sign = -1;
36+
a = Math.abs(a);
37+
}
1138

1239
// Use a deterministic initial guess instead of a random one for
1340
// improved stability. `a / n` generally brings us closer to the
@@ -22,13 +49,14 @@ let nthRoot = (n, a) => {
2249
// Limit the number of iterations to avoid potential infinite loops
2350
// when provided with invalid input.
2451
while (delX > eps && iterations < 1000) {
25-
result = ((n - 1.0) * preResult + a/Math.pow(preResult, n-1)) / n;
52+
result = ((n - 1) * preResult + a / Math.pow(preResult, n - 1)) / n;
2653
delX = Math.abs(result - preResult);
2754
preResult = result;
2855
iterations += 1;
2956
}
3057

31-
return result.toPrecision(6);
58+
result *= sign;
59+
return Number(result.toPrecision(6)).toString();
3260
};
3361

3462
module.exports = {

0 commit comments

Comments
 (0)