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.
610let 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
3462module . exports = {
0 commit comments