Nth root: Difference between revisions
(Added solution for Action!) |
Langurmonkey (talk | contribs) |
||
(29 intermediate revisions by 17 users not shown) | |||
Line 10: | Line 10: | ||
{{trans|Nim}} |
{{trans|Nim}} |
||
< |
<syntaxhighlight lang="11l">F nthroot(a, n) |
||
V result = a |
V result = a |
||
V x = a / n |
V x = a / n |
||
Line 20: | Line 20: | ||
print(nthroot(34.0, 5)) |
print(nthroot(34.0, 5)) |
||
print(nthroot(42.0, 10)) |
print(nthroot(42.0, 10)) |
||
print(nthroot(5.0, 2))</ |
print(nthroot(5.0, 2))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 33: | Line 33: | ||
The 'include' file FORMAT, to format a floating point number, can be found in: |
The 'include' file FORMAT, to format a floating point number, can be found in: |
||
[[360_Assembly_include|Include files 360 Assembly]]. |
[[360_Assembly_include|Include files 360 Assembly]]. |
||
< |
<syntaxhighlight lang="360asm">* Nth root - x**(1/n) - 29/07/2018 |
||
NTHROOT CSECT |
NTHROOT CSECT |
||
USING NTHROOT,R13 base register |
USING NTHROOT,R13 base register |
||
Line 91: | Line 91: | ||
PG DC CL80' ' buffer |
PG DC CL80' ' buffer |
||
REGEQU |
REGEQU |
||
END NTHROOT </ |
END NTHROOT </syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> 1.414213</pre> |
<pre> 1.414213</pre> |
||
Line 97: | Line 97: | ||
=={{header|AArch64 Assembly}}== |
=={{header|AArch64 Assembly}}== |
||
{{works with|as|Raspberry Pi 3B version Buster 64 bits}} |
{{works with|as|Raspberry Pi 3B version Buster 64 bits}} |
||
<syntaxhighlight lang="aarch64 assembly"> |
|||
<lang AArch64 Assembly> |
|||
/* ARM assembly AARCH64 Raspberry PI 3B */ |
/* ARM assembly AARCH64 Raspberry PI 3B */ |
||
/* program nroot64.s */ |
/* program nroot64.s */ |
||
Line 207: | Line 207: | ||
/* for this file see task include a file in language AArch64 assembly */ |
/* for this file see task include a file in language AArch64 assembly */ |
||
.include "../includeARM64.inc" |
.include "../includeARM64.inc" |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Output}} |
{{Output}} |
||
<pre> |
<pre> |
||
Line 217: | Line 217: | ||
{{libheader|Action! Tool Kit}} |
{{libheader|Action! Tool Kit}} |
||
{{libheader|Action! Real Math}} |
{{libheader|Action! Real Math}} |
||
< |
<syntaxhighlight lang="action!">INCLUDE "H6:REALMATH.ACT" |
||
PROC NthRoot(REAL POINTER a,n REAL POINTER res) |
PROC NthRoot(REAL POINTER a,n REAL POINTER res) |
||
Line 262: | Line 262: | ||
Test("7","0.5") |
Test("7","0.5") |
||
Test("12.34","56.78") |
Test("12.34","56.78") |
||
RETURN</ |
RETURN</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Nth_root.png Screenshot from Atari 8-bit computer] |
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Nth_root.png Screenshot from Atari 8-bit computer] |
||
Line 275: | Line 275: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
The implementation is generic and supposed to work with any floating-point type. There is no result accuracy argument of Nth_Root, because the iteration is supposed to be monotonically descending to the root when starts at ''A''. Thus it should converge when this condition gets violated, i.e. when ''x''<sub>''k''+1</sub>''≥''x''<sub>''k''</sub>''. |
The implementation is generic and supposed to work with any floating-point type. There is no result accuracy argument of Nth_Root, because the iteration is supposed to be monotonically descending to the root when starts at ''A''. Thus it should converge when this condition gets violated, i.e. when ''x''<sub>''k''+1</sub>''≥''x''<sub>''k''</sub>''. |
||
<syntaxhighlight lang="ada"> |
|||
<lang Ada> |
|||
with Ada.Text_IO; use Ada.Text_IO; |
with Ada.Text_IO; use Ada.Text_IO; |
||
Line 303: | Line 303: | ||
Put_Line ("5642.0 125th =" & Long_Float'Image (Long_Nth_Root (5642.0, 125))); |
Put_Line ("5642.0 125th =" & Long_Float'Image (Long_Nth_Root (5642.0, 125))); |
||
end Test_Nth_Root; |
end Test_Nth_Root; |
||
</syntaxhighlight> |
|||
</lang> |
|||
Sample output: |
Sample output: |
||
<pre> |
<pre> |
||
Line 319: | Line 319: | ||
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}} |
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}} |
||
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - missing transput, and missing extended precision}} |
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - missing transput, and missing extended precision}} |
||
< |
<syntaxhighlight lang="algol68">REAL default p = 0.001; |
||
PROC nth root = (INT n, LONG REAL a, p)LONG REAL: |
PROC nth root = (INT n, LONG REAL a, p)LONG REAL: |
||
Line 343: | Line 343: | ||
10 ROOT ( LONG 7131.5 ** 10 ), |
10 ROOT ( LONG 7131.5 ** 10 ), |
||
5 ROOT 34)) |
5 ROOT 34)) |
||
)</ |
)</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 354: | Line 354: | ||
=={{header|ALGOL W}}== |
=={{header|ALGOL W}}== |
||
< |
<syntaxhighlight lang="algolw">begin |
||
% nth root algorithm % |
% nth root algorithm % |
||
% returns the nth root of A, A must be > 0 % |
% returns the nth root of A, A must be > 0 % |
||
Line 378: | Line 378: | ||
write( nthRoot( 7131.5 ** 10, 10, 1'-5 ) ); |
write( nthRoot( 7131.5 ** 10, 10, 1'-5 ) ); |
||
write( nthRoot( 64, 6, 1'-5 ) ); |
write( nthRoot( 64, 6, 1'-5 ) ); |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 387: | Line 387: | ||
=={{header|ARM Assembly}}== |
=={{header|ARM Assembly}}== |
||
{{works with|as|Raspberry Pi}} |
{{works with|as|Raspberry Pi}} |
||
<syntaxhighlight lang="arm assembly"> |
|||
<lang ARM Assembly> |
|||
/* ARM assembly Raspberry PI */ |
/* ARM assembly Raspberry PI */ |
||
/* program nroot.s */ |
/* program nroot.s */ |
||
Line 490: | Line 490: | ||
dfPrec: .double 0f1E-10 @ précision |
dfPrec: .double 0f1E-10 @ précision |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Arturo}}== |
|||
{{trans|Nim}} |
|||
<syntaxhighlight lang="rebol">nthRoot: function [a,n][ |
|||
N: to :floating n |
|||
result: a |
|||
x: a / N |
|||
while [0.000000000000001 < abs result-x][ |
|||
x: result |
|||
result: (1//n) * add (n-1)*x a/pow x n-1 |
|||
] |
|||
return result |
|||
] |
|||
print nthRoot 34.0 5 |
|||
print nthRoot 42.0 10 |
|||
print nthRoot 5.0 2</syntaxhighlight> |
|||
{{out}} |
|||
<pre>2.024397458499885 |
|||
1.453198460282268 |
|||
2.23606797749979</pre> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
< |
<syntaxhighlight lang="autohotkey">p := 0.000001 |
||
MsgBox, % nthRoot( 10, 7131.5**10, p) "`n" |
MsgBox, % nthRoot( 10, 7131.5**10, p) "`n" |
||
Line 511: | Line 534: | ||
} |
} |
||
Return, x2 |
Return, x2 |
||
}</ |
}</syntaxhighlight> |
||
Message box shows: |
Message box shows: |
||
<pre>7131.500000 |
<pre>7131.500000 |
||
Line 519: | Line 542: | ||
=={{header|AutoIt}}== |
=={{header|AutoIt}}== |
||
< |
<syntaxhighlight lang="autoit">;AutoIt Version: 3.2.10.0 |
||
$A=4913 |
$A=4913 |
||
$n=3 |
$n=3 |
||
Line 544: | Line 567: | ||
EndIf |
EndIf |
||
Return nth_root_rec($A,$n,((($n-1)*$x)+($A/$x^($n-1)))/$n) |
Return nth_root_rec($A,$n,((($n-1)*$x)+($A/$x^($n-1)))/$n) |
||
EndFunc</ |
EndFunc</syntaxhighlight> |
||
output : |
output : |
||
<pre>20 |
<pre>20 |
||
Line 556: | Line 579: | ||
=={{header|AWK}}== |
=={{header|AWK}}== |
||
< |
<syntaxhighlight lang="awk"> |
||
#!/usr/bin/awk -f |
#!/usr/bin/awk -f |
||
BEGIN { |
BEGIN { |
||
Line 579: | Line 602: | ||
return x |
return x |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Sample output: |
Sample output: |
||
Line 597: | Line 620: | ||
This function is fairly generic MS BASIC. It could likely be used in most modern BASICs with little or no change. |
This function is fairly generic MS BASIC. It could likely be used in most modern BASICs with little or no change. |
||
< |
<syntaxhighlight lang="qbasic">FUNCTION RootX (tBase AS DOUBLE, tExp AS DOUBLE, diffLimit AS DOUBLE) AS DOUBLE |
||
DIM tmp1 AS DOUBLE, tmp2 AS DOUBLE |
DIM tmp1 AS DOUBLE, tmp2 AS DOUBLE |
||
' Initial guess: |
' Initial guess: |
||
Line 607: | Line 630: | ||
LOOP WHILE (ABS(tmp1 - tmp2) > diffLimit) |
LOOP WHILE (ABS(tmp1 - tmp2) > diffLimit) |
||
RootX = tmp1 |
RootX = tmp1 |
||
END FUNCTION</ |
END FUNCTION</syntaxhighlight> |
||
Note that for the above to work in QBasic, the function definition needs to be changed like so: |
Note that for the above to work in QBasic, the function definition needs to be changed like so: |
||
< |
<syntaxhighlight lang="qbasic">FUNCTION RootX# (tBase AS DOUBLE, tExp AS DOUBLE, diffLimit AS DOUBLE)</syntaxhighlight> |
||
The function is called like so: |
The function is called like so: |
||
< |
<syntaxhighlight lang="qbasic">PRINT "The "; e; "th root of "; b; " is "; RootX(b, e, .000001)</syntaxhighlight> |
||
Sample output: |
Sample output: |
||
Line 623: | Line 646: | ||
See also the [[#Liberty BASIC|Liberty BASIC]] and [[#PureBasic|PureBasic]] solutions. |
See also the [[#Liberty BASIC|Liberty BASIC]] and [[#PureBasic|PureBasic]] solutions. |
||
=={{header|Basic09}}== |
==={{header|Basic09}}=== |
||
{{Works with |OS9 operating system -- RUN nth(root,number,precision)}} |
{{Works with |OS9 operating system -- RUN nth(root,number,precision)}} |
||
<syntaxhighlight lang="basic09"> |
|||
<lang Basic09> |
|||
PROCEDURE nth |
PROCEDURE nth |
||
PARAM N : INTEGER; A, P : REAL |
PARAM N : INTEGER; A, P : REAL |
||
Line 639: | Line 662: | ||
PRINT "The Root is: ";TEMP1 |
PRINT "The Root is: ";TEMP1 |
||
END |
END |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header| |
==={{header|BASIC256}}=== |
||
<syntaxhighlight lang="freebasic">function nth_root(n, a) |
|||
precision = 0.0001 |
|||
dim x(2) |
|||
x[0] = a |
|||
x[1] = a /n |
|||
while abs(x[1] - x[0]) > precision |
|||
x[0] = x[1] |
|||
x[1] = ((n -1.0) * x[1] +a / x[1]^(n -1.0)) / n |
|||
end while |
|||
return x[1] |
|||
end function |
|||
print " n 5643 ^ 1 / n nth_root ^ n" |
|||
print " --------------------------------------" |
|||
for n = 3 to 11 step 2 |
|||
tmp = nth_root(n, 5643) |
|||
print " "; n; " "; tmp; chr(9); (tmp ^ n) |
|||
next n |
|||
print |
|||
for n = 25 to 125 step 25 |
|||
tmp = nth_root(n, 5643) |
|||
print n; " "; tmp; chr(9); (tmp ^ n) |
|||
next n</syntaxhighlight> |
|||
==={{header|BBC BASIC}}=== |
|||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
< |
<syntaxhighlight lang="bbcbasic"> *FLOAT 64 |
||
@% = &D0D |
@% = &D0D |
||
PRINT "Cube root of 5 is "; FNroot(3, 5, 0) |
PRINT "Cube root of 5 is "; FNroot(3, 5, 0) |
||
Line 655: | Line 704: | ||
SWAP x0, x1 |
SWAP x0, x1 |
||
UNTIL ABS (x0 - x1) <= d |
UNTIL ABS (x0 - x1) <= d |
||
= x0</ |
= x0</syntaxhighlight> |
||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Cube root of 5 is 1.709975946677 |
Cube root of 5 is 1.709975946677 |
||
125th root of 5643 is 1.071549111198 |
125th root of 5643 is 1.071549111198 |
||
</pre> |
|||
==={{header|Chipmunk Basic}}=== |
|||
{{trans|S-BASIC}} |
|||
<syntaxhighlight lang="basic"> |
|||
10 rem Nth root |
|||
20 print "Finding the nth root of 144 to 6 decimal places" |
|||
30 print " x n root" |
|||
40 print "------------------------" |
|||
50 for i = 1 to 8 |
|||
60 print using "### ";144; |
|||
70 print using "#### ";i; |
|||
80 print using "###.######";nthroot(i,144,1.000000E-07) |
|||
90 next i |
|||
100 end |
|||
1000 sub nthroot(n,x,precision) |
|||
1010 rem Returns the nth root of value x to stated precision |
|||
1020 x0 = x |
|||
1030 x1 = x/n ' - initial guess |
|||
1040 while abs(x1-x0) > precision |
|||
1050 x0 = x1 |
|||
1060 x1 = ((n-1)*x1+x/x1^(n-1))/n |
|||
1070 wend |
|||
1080 nthroot = x1 |
|||
1090 end sub |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Finding the nth root of 144 to 6 decimal places |
|||
x n root |
|||
------------------------ |
|||
144 1 144.000000 |
|||
144 2 12.000000 |
|||
144 3 5.241483 |
|||
144 4 3.464102 |
|||
144 5 2.701920 |
|||
144 6 2.289428 |
|||
144 7 2.033937 |
|||
144 8 1.861210 |
|||
</pre> |
|||
==={{header|Craft Basic}}=== |
|||
<syntaxhighlight lang="basic">precision 6 |
|||
let a = int(rnd * 5999) + 2 |
|||
print "calculating nth root of ", a, "..." |
|||
for n = 1 to 10 |
|||
gosub nroot |
|||
print n, " : ", y |
|||
next n |
|||
end |
|||
sub nroot |
|||
let p = .00001 |
|||
let x = a |
|||
let y = a / n |
|||
do |
|||
if abs(x - y) > p then |
|||
let x = y |
|||
let y = ((n - 1) * y + a / y ^ (n - 1)) / n |
|||
endif |
|||
wait |
|||
loop abs(x - y) > p |
|||
return</syntaxhighlight> |
|||
{{out| Output}}<pre>calculating nth root of 634... |
|||
1 : 634 |
|||
2 : 25.179356 |
|||
3 : 8.590724 |
|||
4 : 5.017903 |
|||
5 : 3.634275 |
|||
6 : 2.930994 |
|||
7 : 2.513613 |
|||
8 : 2.240068 |
|||
9 : 2.048063 |
|||
10 : 1.906378</pre> |
|||
==={{header|FreeBASIC}}=== |
|||
<syntaxhighlight lang="freebasic">' version 14-01-2019 |
|||
' compile with: fbc -s console |
|||
Function nth_root(n As Integer, number As Double) As Double |
|||
Dim As Double a1 = number / n, a2 , a3 |
|||
Do |
|||
a3 = Abs(a2 - a1) |
|||
a2 = ((n -1) * a1 + number / a1 ^ (n -1)) / n |
|||
Swap a1, a2 |
|||
Loop Until Abs(a2 - a1) = a3 |
|||
Return a1 |
|||
End Function |
|||
' ------=< MAIN >=------ |
|||
Dim As UInteger n |
|||
Dim As Double tmp |
|||
Print |
|||
Print " n 5643 ^ 1 / n nth_root ^ n" |
|||
Print " ------------------------------------" |
|||
For n = 3 To 11 Step 2 |
|||
tmp = nth_root(n, 5643) |
|||
Print Using " ### ###.######## ####.########"; n; tmp; tmp ^ n |
|||
Next |
|||
Print |
|||
For n = 25 To 125 Step 25 |
|||
tmp = nth_root(n, 5643) |
|||
Print Using " ### ###.######## ####.########"; n; tmp; tmp ^ n |
|||
Next |
|||
' empty keyboard buffer |
|||
While Inkey <> "" : Wend |
|||
Print : Print "hit any key to end program" |
|||
Sleep |
|||
End</syntaxhighlight> |
|||
{{out}} |
|||
<pre> n 5643 ^ 1 / n nth_root ^ n |
|||
------------------------------------ |
|||
3 17.80341642 5643.00000000 |
|||
5 5.62732516 5643.00000000 |
|||
7 3.43502583 5643.00000000 |
|||
9 2.61116581 5643.00000000 |
|||
11 2.19303907 5643.00000000 |
|||
25 1.41273402 5643.00000000 |
|||
50 1.18858488 5643.00000000 |
|||
75 1.12207047 5643.00000000 |
|||
100 1.09022240 5643.00000000 |
|||
125 1.07154911 5643.00000000</pre> |
|||
==={{header|FutureBasic}}=== |
|||
<syntaxhighlight lang="futurebasic">window 1 |
|||
local fn NthRoot( root as long, a as long, precision as double ) as double |
|||
double x0, x1 |
|||
x0 = a : x1 = a /root |
|||
while ( abs( x1 - x0 ) > precision ) |
|||
x0 = x1 |
|||
x1 = ( ( root -1.0 ) * x1 + a / x1 ^ ( root -1.0 ) ) /root |
|||
wend |
|||
end fn = x1 |
|||
print " 125th Root of 5643 Precision .001",, using "#.###############"; fn NthRoot( 125, 5642, 0.001 ) |
|||
print " 125th Root of 5643 Precision .001",, using "#.###############"; fn NthRoot( 125, 5642, 0.001 ) |
|||
print " 125th Root of 5643 Precision .00001", using "#.###############"; fn NthRoot( 125, 5642, 0.00001 ) |
|||
print " Cube Root of 27 Precision .00001", using "#.###############"; fn NthRoot( 3, 27, 0.00001 ) |
|||
print "Square Root of 2 Precision .00001", using "#.###############"; fn NthRoot( 2, 2, 0.00001 ) |
|||
print "Square Root of 2 Precision .00001", using "#.###############"; sqr(2) // Processor floating point calc deviation |
|||
print " 10th Root of 1024 Precision .00001", using "#.###############"; fn NthRoot( 10, 1024, 0.00001 ) |
|||
print " 5th Root of 34 Precision .00001", using "#.###############"; fn NthRoot( 5, 34, 0.00001 ) |
|||
HandleEvents</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
125th Root of 5643 Precision .001 1.071559602191682 |
|||
125th Root of 5643 Precision .001 1.071559602191682 |
|||
125th Root of 5643 Precision .00001 1.071547591944772 |
|||
Cube Root of 27 Precision .00001 3.000000000000002 |
|||
Square Root of 2 Precision .00001 1.414213562374690 |
|||
Square Root of 2 Precision .00001 1.414213562373095 |
|||
10th Root of 1024 Precision .00001 2.000000000000000 |
|||
5th Root of 34 Precision .00001 2.024397458499885 |
|||
</pre> |
|||
==={{header|Liberty BASIC}}=== |
|||
{{works with|Just BASIC}} |
|||
<syntaxhighlight lang="lb"> |
|||
print "First estimate is: ", using( "#.###############", NthRoot( 125, 5642, 0.001 )); |
|||
print " ... and better is: ", using( "#.###############", NthRoot( 125, 5642, 0.00001)) |
|||
print "125'th root of 5642 by LB's exponentiation operator is "; using( "#.###############", 5642^(1 /125)) |
|||
print "27^(1 / 3)", using( "#.###############", NthRoot( 3, 27, 0.00001)) |
|||
print "2^(1 / 2)", using( "#.###############", NthRoot( 2, 2, 0.00001)) |
|||
print "1024^(1 /10)", using( "#.###############", NthRoot( 10, 1024, 0.00001)) |
|||
wait |
|||
function NthRoot( n, A, p) |
|||
x( 0) =A |
|||
x( 1) =A /n |
|||
while abs( x( 1) -x( 0)) >p |
|||
x( 0) =x( 1) |
|||
x( 1) =( ( n -1.0) *x( 1) +A /x( 1)^( n -1.0)) /n |
|||
wend |
|||
NthRoot =x( 1) |
|||
end function |
|||
end |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
First estimate is: 1.071559602191682 ... and better is: 1.071547591944771 |
|||
125'th root of 5642 by LB's exponentiation operator is 1.071547591944767 |
|||
27^(1 / 3) 3.000000000000002 |
|||
2^(1 / 2) 1.414213562374690 |
|||
1024^(1 /10) 2.000000000000000 |
|||
</pre> |
|||
==={{header|PureBasic}}=== |
|||
<syntaxhighlight lang="purebasic">#Def_p=0.001 |
|||
Procedure.d Nth_root(n.i, A.d, p.d=#Def_p) |
|||
Protected Dim x.d(1) |
|||
x(0)=A: x(1)=A/n |
|||
While Abs(x(1)-x(0))>p |
|||
x(0)=x(1) |
|||
x(1)=((n-1.0)*x(1)+A/Pow(x(1),n-1.0))/n |
|||
Wend |
|||
ProcedureReturn x(1) |
|||
EndProcedure |
|||
;////////////////////////////// |
|||
Debug "125'th root of 5642 is" |
|||
Debug Pow(5642,1/125) |
|||
Debug "First estimate is:" |
|||
Debug Nth_root(125,5642) |
|||
Debug "And better:" |
|||
Debug Nth_root(125,5642,0.00001)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
125'th root of 5642 is |
|||
1.0715475919447675 |
|||
First estimate is: |
|||
1.0715596021916822 |
|||
And better: |
|||
1.0715475919447714 |
|||
</pre> |
|||
==={{header|Run BASIC}}=== |
|||
<syntaxhighlight lang="runbasic">print "Root 125th Root of 5643 Precision .001 ";using( "#.###############", NthRoot( 125, 5642, 0.001 )) |
|||
print "125th Root of 5643 Precision .001 ";using( "#.###############", NthRoot( 125, 5642, 0.001 )) |
|||
print "125th Root of 5643 Precision .00001 ";using( "#.###############", NthRoot( 125, 5642, 0.00001)) |
|||
print " 3rd Root of 27 Precision .00001 ";using( "#.###############", NthRoot( 3, 27, 0.00001)) |
|||
print " 2nd Root of 2 Precision .00001 ";using( "#.###############", NthRoot( 2, 2, 0.00001)) |
|||
print " 10th Root of 1024 Precision .00001 ";using( "#.###############", NthRoot( 10, 1024, 0.00001)) |
|||
wait |
|||
function NthRoot( root, A, precision) |
|||
x0 = A |
|||
x1 = A /root |
|||
while abs( x1 -x0) >precision |
|||
x0 = x1 |
|||
x1 = x1 / 1.0 ' force float |
|||
x1 = (( root -1.0) *x1 +A /x1^( root -1.0)) /root |
|||
wend |
|||
NthRoot =x1 |
|||
end function |
|||
end</syntaxhighlight> |
|||
<pre>125th Root of 5643 Precision .001 1.071559602456735 |
|||
125th Root of 5643 Precision .00001 1.071547591944771 |
|||
3rd Root of 27 Precision .00001 3.000000000000001 |
|||
2nd Root of 2 Precision .00001 1.414213562374690 |
|||
10th Root of 1024 Precision .00001 2.000000000000000</pre> |
|||
==={{header|S-BASIC}}=== |
|||
When single precision results are sufficient for the task at hand, resort to Newton's method |
|||
seems unnecessarily cumbersome, given the ready availability of S-BASIC's built-in exp and |
|||
natural log functions. |
|||
<syntaxhighlight lang="basic"> |
|||
rem - return nth root of x |
|||
function nthroot(x, n = real) = real |
|||
end = exp((1.0 / n) * log(x)) |
|||
rem - exercise the routine by finding successive roots of 144 |
|||
var i = integer |
|||
print "Finding the nth root of x" |
|||
print " x n root" |
|||
print "-----------------------" |
|||
for i = 1 to 8 |
|||
print using "### #### ###.####"; 144; i; nthroot(144, i) |
|||
next i |
|||
end |
|||
</syntaxhighlight> |
|||
But if the six or seven digits supported by S-BASIC's single-precision REAL data type is insufficient, Newton's Method is the way to go, given that the built-in exp and natural log functions are only single-precision. |
|||
<syntaxhighlight lang="basic"> |
|||
rem - return the nth root of real.double value x to stated precision |
|||
function nthroot(n, x, precision = real.double) = real.double |
|||
var x0, x1 = real.double |
|||
x0 = x |
|||
x1 = x / n rem - initial guess |
|||
while abs(x1 - x0) > precision do |
|||
begin |
|||
x0 = x1 |
|||
x1 = ((n-1.0) * x1 + x / x1 ^ (n-1.0)) / n |
|||
end |
|||
end = x1 |
|||
rem -- exercise the routine |
|||
var i = integer |
|||
print "Finding the nth root of 144 to 6 decimal places" |
|||
print " x n root" |
|||
print "------------------------" |
|||
for i = 1 to 8 |
|||
print using "### #### ###.######"; 144; i; nthroot(i, 144.0, 1E-7) |
|||
next i |
|||
end |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
From the second version of the program. |
|||
<pre> |
|||
Finding the nth root of 144 to 6 decimal places |
|||
x n root |
|||
------------------------- |
|||
144 1 144.000000 |
|||
144 2 12.000000 |
|||
144 3 5.241483 |
|||
144 4 3.464102 |
|||
144 5 2.701920 |
|||
144 6 2.289428 |
|||
144 7 2.033937 |
|||
144 8 1.861210 |
|||
</pre> |
|||
==={{header|True BASIC}}=== |
|||
<syntaxhighlight lang="qbasic">FUNCTION Nroot (n, a) |
|||
LET precision = .00001 |
|||
LET x1 = a |
|||
LET x2 = a / n |
|||
DO WHILE ABS(x2 - x1) > precision |
|||
LET x1 = x2 |
|||
LET x2 = ((n - 1) * x2 + a / x2 ^ (n - 1)) / n |
|||
LOOP |
|||
LET Nroot = x2 |
|||
END FUNCTION |
|||
PRINT " n 5643 ^ 1 / n nth_root ^ n" |
|||
PRINT " ------------------------------------" |
|||
FOR n = 3 TO 11 STEP 2 |
|||
LET tmp = Nroot(n, 5643) |
|||
PRINT USING "####": n; |
|||
PRINT " "; |
|||
PRINT USING "###.########": tmp; |
|||
PRINT " "; |
|||
PRINT USING "####.########": (tmp ^ n) |
|||
NEXT n |
|||
PRINT |
|||
FOR n = 25 TO 125 STEP 25 |
|||
LET tmp = Nroot(n, 5643) |
|||
PRINT USING "####": n; |
|||
PRINT " "; |
|||
PRINT USING "###.########": tmp; |
|||
PRINT " "; |
|||
PRINT USING "####.########": (tmp ^ n) |
|||
NEXT n |
|||
END</syntaxhighlight> |
|||
==={{header|Yabasic}}=== |
|||
{{trans|AWK}} |
|||
<syntaxhighlight lang="yabasic">data 10, 1024, 3, 27, 2, 2, 125, 5642, 4, 16, 0, 0 |
|||
do |
|||
read e, b |
|||
if e = 0 break |
|||
print "The ", e, "th root of ", b, " is ", b^(1/e), " (", nthroot(b, e), ")" |
|||
loop |
|||
sub nthroot(y, n) |
|||
local eps, x, d, e |
|||
eps = 1e-15 // relative accuracy |
|||
x = 1 |
|||
repeat |
|||
d = ( y / ( x^(n-1) ) - x ) / n |
|||
x = x + d |
|||
e = eps * x // absolute accuracy |
|||
until(not(d < -e or d > e )) |
|||
return x |
|||
end sub</syntaxhighlight> |
|||
==={{header|VBA}}=== |
|||
{{trans|Phix}} |
|||
The internal power operator "^" is used in stead of an auxiliary pow_ function and the accuracy has been reduced. |
|||
<syntaxhighlight lang="vb">Private Function nth_root(y As Double, n As Double) |
|||
Dim eps As Double: eps = 0.00000000000001 '-- relative accuracy |
|||
Dim x As Variant: x = 1 |
|||
Do While True |
|||
d = (y / x ^ (n - 1) - x) / n |
|||
x = x + d |
|||
e = eps * x '-- absolute accuracy |
|||
If d > -e And d < e Then |
|||
Exit Do |
|||
End If |
|||
Loop |
|||
Debug.Print y; n; x; y ^ (1 / n) |
|||
End Function |
|||
Public Sub main() |
|||
nth_root 1024, 10 |
|||
nth_root 27, 3 |
|||
nth_root 2, 2 |
|||
nth_root 5642, 125 |
|||
nth_root 7, 0.5 |
|||
nth_root 4913, 3 |
|||
nth_root 8, 3 |
|||
nth_root 16, 2 |
|||
nth_root 16, 4 |
|||
nth_root 125, 3 |
|||
nth_root 1000000000, 3 |
|||
nth_root 1000000000, 9 |
|||
End Sub</syntaxhighlight>{{out}} |
|||
<pre> 1024 10 2 2 |
|||
27 3 3 3 |
|||
2 2 1,41421356237309 1,4142135623731 |
|||
5642 125 1,07154759194477 1,07154759194477 |
|||
7 0,5 49 49 |
|||
4913 3 17 17 |
|||
8 3 2 2 |
|||
16 2 4 4 |
|||
16 4 2 2 |
|||
125 3 5 5 |
|||
1000000000 3 1000 1000 |
|||
1000000000 9 10 10 |
|||
</pre> |
</pre> |
||
=={{header|bc}}== |
=={{header|bc}}== |
||
< |
<syntaxhighlight lang="bc">/* Take the nth root of 'a' (a positive real number). |
||
* 'n' must be an integer. |
* 'n' must be an integer. |
||
* Result will have 'd' digits after the decimal point. |
* Result will have 'd' digits after the decimal point. |
||
Line 692: | Line 1,181: | ||
scale = o |
scale = o |
||
return(y) |
return(y) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|BQN}}== |
=={{header|BQN}}== |
||
Line 701: | Line 1,190: | ||
<code>_while_</code> is a [https://mlochbaum.github.io/bqncrate/ BQNcrate] idiom used for unbounded looping here. |
<code>_while_</code> is a [https://mlochbaum.github.io/bqncrate/ BQNcrate] idiom used for unbounded looping here. |
||
< |
<syntaxhighlight lang="bqn">_while_ ← {𝔽⍟𝔾∘𝔽_𝕣_𝔾∘𝔽⍟𝔾𝕩} |
||
Root ← √ |
Root ← √ |
||
Root1 ← ⋆⟜÷˜ |
Root1 ← ⋆⟜÷˜ |
||
Line 722: | Line 1,211: | ||
•Show 3 Root1 5 |
•Show 3 Root1 5 |
||
•Show 3 Root2 5 |
•Show 3 Root2 5 |
||
•Show 3 Root2 5‿1E¯16</ |
•Show 3 Root2 5‿1E¯16</syntaxhighlight> |
||
<lang>1.7099759466766968 |
<syntaxhighlight lang="text">1.7099759466766968 |
||
1.7099759466766968 |
1.7099759466766968 |
||
1.7099759641072136 |
1.7099759641072136 |
||
1.709975946676697</ |
1.709975946676697</syntaxhighlight> |
||
[https://mlochbaum.github.io/BQN/try.html#code=X3doaWxlXyDihpAge/CdlL3ijZ/wnZS+4oiY8J2UvV/wnZWjX/CdlL7iiJjwnZS94o2f8J2UvvCdlal9ClJvb3Qg4oaQIOKImgpSb290MSDihpAg4ouG4p+cw7fLnApSb290MiDihpAgewogIG4g8J2ViiBh4oC/cHJlYzoKICAx4oqRewogICAgcOKAv3g6CiAgICDin6gKICAgICAgeAogICAgICAoKHAgw5cgbiAtIDEpICsgYSDDtyBwIOKLhiBuIC0gMSkgw7cgbgogICAg4p+pCiAgfSBfd2hpbGVfIHsKICAgIHDigL94OgogICAgcHJlYyDiiaQgfCBwIC0geAogIH0g4p+oYSwg4oyKYcO3buKfqTsKICDwnZWoIPCdlYog8J2VqTog8J2VqCDwnZWKIPCdlanigL8xRcKvNQp9CgrigKJTaG93IDMgUm9vdCA1CuKAolNob3cgMyBSb290MSA1CuKAolNob3cgMyBSb290MiA1CuKAolNob3cgMyBSb290MiA14oC/MUXCrzE2Cgo= Try It!] |
[https://mlochbaum.github.io/BQN/try.html#code=X3doaWxlXyDihpAge/CdlL3ijZ/wnZS+4oiY8J2UvV/wnZWjX/CdlL7iiJjwnZS94o2f8J2UvvCdlal9ClJvb3Qg4oaQIOKImgpSb290MSDihpAg4ouG4p+cw7fLnApSb290MiDihpAgewogIG4g8J2ViiBh4oC/cHJlYzoKICAx4oqRewogICAgcOKAv3g6CiAgICDin6gKICAgICAgeAogICAgICAoKHAgw5cgbiAtIDEpICsgYSDDtyBwIOKLhiBuIC0gMSkgw7cgbgogICAg4p+pCiAgfSBfd2hpbGVfIHsKICAgIHDigL94OgogICAgcHJlYyDiiaQgfCBwIC0geAogIH0g4p+oYSwg4oyKYcO3buKfqTsKICDwnZWoIPCdlYog8J2VqTog8J2VqCDwnZWKIPCdlanigL8xRcKvNQp9CgrigKJTaG93IDMgUm9vdCA1CuKAolNob3cgMyBSb290MSA1CuKAolNob3cgMyBSb290MiA1CuKAolNob3cgMyBSb290MiA14oC/MUXCrzE2Cgo= Try It!] |
||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
Bracmat |
Until 2023, Bracmat did not have floating point numbers as primitive type. Instead we had to use rational numbers. This code is not fast! |
||
< |
<syntaxhighlight lang="bracmat">( ( root |
||
= n a d x0 x1 d2 rnd 10-d |
= n a d x0 x1 d2 rnd 10-d |
||
. ( rnd { For 'rounding' rational numbers = keep number of digits within bounds. } |
. ( rnd { For 'rounding' rational numbers = keep number of digits within bounds. } |
||
Line 759: | Line 1,248: | ||
& show$(2,2,100) |
& show$(2,2,100) |
||
& show$(125,5642,20) |
& show$(125,5642,20) |
||
)</ |
)</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>1024^(1/10)=2,00000000000000000000*10E0 |
<pre>1024^(1/10)=2,00000000000000000000*10E0 |
||
Line 765: | Line 1,254: | ||
2^(1/2)=1,4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727*10E0 |
2^(1/2)=1,4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727*10E0 |
||
5642^(1/125)=1,07154759194476751170*10E0</pre> |
5642^(1/125)=1,07154759194476751170*10E0</pre> |
||
This is a floating point reimplementation of the C solution: |
|||
{{trans|C}} |
|||
<syntaxhighlight lang="bracmat"> "The body of Pow will be compiled twice: once as the the code hidden in the |
|||
UFP object called 'POW' (see below) and once as a local function of the code |
|||
hidden in the UFP object called 'Root' (also see below)." |
|||
& ( Pow |
|||
= (s.x) (s.e) |
|||
. 1:?r |
|||
& 0:?i |
|||
& whl |
|||
' ( !i:<!e |
|||
& !x*!r:?r |
|||
& 1+!i:?i |
|||
) |
|||
& !r |
|||
) |
|||
& "The next expression is a macro expression that expands $Pow to the body of |
|||
the Pow function defined above. |
|||
There is another local function, called 'even'." |
|||
& |
|||
' ( (s.n) (s.x) |
|||
. (Pow=$Pow) |
|||
& ( even |
|||
= (s.v) |
|||
. floor$(!v*1/2):?v/2 |
|||
& subtract$(!v,2*!v/2) |
|||
) |
|||
& ( !x:0 |
|||
| ( !n:<1 |
|||
| !x:<0&even$!n:0 |
|||
) |
|||
& divide$(0,0) |
|||
| 0x1p-52*10:?EPS |
|||
& 0x1p-52*-10:?EPS- |
|||
& 1:?r |
|||
& !n+-1:?n-1 |
|||
& whl |
|||
' ( divide |
|||
$ (divide$(!x,Pow$(!r,!n-1))+-1*!r,!n) |
|||
: ?d |
|||
& !d+!r:?r |
|||
& (!d:~<!EPS|!d:~>!EPS-) |
|||
) |
|||
& !r |
|||
) |
|||
) |
|||
: (=?root) |
|||
& "Create two UFP objects, POW and ROOT. They are each others' inverse." |
|||
& new$(UFP,Pow):?POW |
|||
& new$(UFP,root):?Root |
|||
& 15:?n |
|||
& (POW..go)$("-3.14159",15):?x |
|||
& out$((Root..go)$(!n,!x));</syntaxhighlight> |
|||
Output: |
|||
<pre>-3.1415899999999999E+00</pre> |
|||
=={{header|C}}== |
=={{header|C}}== |
||
Implemented without using math library, because if we were to use <code>pow()</code>, the whole exercise wouldn't make sense. |
Implemented without using math library, because if we were to use <code>pow()</code>, the whole exercise wouldn't make sense. |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <float.h> |
#include <float.h> |
||
Line 802: | Line 1,349: | ||
return 0; |
return 0; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
Almost exactly how C works. |
Almost exactly how C works. |
||
< |
<syntaxhighlight lang="csharp"> |
||
static void Main(string[] args) |
static void Main(string[] args) |
||
{ |
{ |
||
Line 828: | Line 1,375: | ||
return x[0]; |
return x[0]; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
< |
<syntaxhighlight lang="cpp">double NthRoot(double m_nValue, double index, double guess, double pc) |
||
{ |
{ |
||
double result = guess; |
double result = guess; |
||
Line 844: | Line 1,391: | ||
return result; |
return result; |
||
}; |
}; |
||
</syntaxhighlight> |
|||
</lang> |
|||
< |
<syntaxhighlight lang="cpp">double NthRoot(double value, double degree) |
||
{ |
{ |
||
return pow(value, (double)(1 / degree)); |
return pow(value, (double)(1 / degree)); |
||
}; |
}; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
< |
<syntaxhighlight lang="clojure"> |
||
(ns test-project-intellij.core |
(ns test-project-intellij.core |
||
(:gen-class)) |
(:gen-class)) |
||
Line 879: | Line 1,426: | ||
(recur A n guess-current (+ guess-current (calc-delta A guess-current n)))))) ; iterate answer using tail recursion |
(recur A n guess-current (+ guess-current (calc-delta A guess-current n)))))) ; iterate answer using tail recursion |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
<syntaxhighlight lang="cobol"> |
|||
IDENTIFICATION DIVISION. |
IDENTIFICATION DIVISION. |
||
PROGRAM-ID. Nth-Root. |
PROGRAM-ID. Nth-Root. |
||
Line 981: | Line 1,529: | ||
END-PROGRAM. |
END-PROGRAM. |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,004: | Line 1,552: | ||
=={{header|CoffeeScript}}== |
=={{header|CoffeeScript}}== |
||
< |
<syntaxhighlight lang="coffeescript"> |
||
nth_root = (A, n, precision=0.0000000000001) -> |
nth_root = (A, n, precision=0.0000000000001) -> |
||
x = 1 |
x = 1 |
||
Line 1,031: | Line 1,579: | ||
root = nth_root x, n |
root = nth_root x, n |
||
console.log "#{x} root #{n} = #{root} (root^#{n} = #{Math.pow root, n})" |
console.log "#{x} root #{n} = #{root} (root^#{n} = #{Math.pow root, n})" |
||
</syntaxhighlight> |
|||
</lang> |
|||
output |
output |
||
<lang> |
<syntaxhighlight lang="text"> |
||
> coffee nth_root.coffee |
> coffee nth_root.coffee |
||
8 root 3 = 2 (root^3 = 8) |
8 root 3 = 2 (root^3 = 8) |
||
Line 1,046: | Line 1,594: | ||
100 root 5 = 2.5118864315095806 (root^5 = 100.0000000000001) |
100 root 5 = 2.5118864315095806 (root^5 = 100.0000000000001) |
||
100 root 10 = 1.5848931924611134 (root^10 = 99.99999999999993) |
100 root 10 = 1.5848931924611134 (root^10 = 99.99999999999993) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Line 1,052: | Line 1,600: | ||
This version does not check for cycles in <var>x<sub>i</sub></var> and <var>x<sub>i+1</sub></var>, but finishes when the difference between them drops below <var>ε</var>. The initial guess can be provided, but defaults to <var>n-1</var>. |
This version does not check for cycles in <var>x<sub>i</sub></var> and <var>x<sub>i+1</sub></var>, but finishes when the difference between them drops below <var>ε</var>. The initial guess can be provided, but defaults to <var>n-1</var>. |
||
< |
<syntaxhighlight lang="lisp">(defun nth-root (n a &optional (epsilon .0001) (guess (1- n))) |
||
(assert (and (> n 1) (> a 0))) |
(assert (and (> n 1) (> a 0))) |
||
(flet ((next (x) |
(flet ((next (x) |
||
Line 1,060: | Line 1,608: | ||
(do* ((xi guess xi+1) |
(do* ((xi guess xi+1) |
||
(xi+1 (next xi) (next xi))) |
(xi+1 (next xi) (next xi))) |
||
((< (abs (- xi+1 xi)) epsilon) xi+1))))</ |
((< (abs (- xi+1 xi)) epsilon) xi+1))))</syntaxhighlight> |
||
<code>nth-root</code> may return rationals rather than floating point numbers, so easy checking for correctness may require coercion to floats. For instance, |
<code>nth-root</code> may return rationals rather than floating point numbers, so easy checking for correctness may require coercion to floats. For instance, |
||
< |
<syntaxhighlight lang="lisp">(let* ((r (nth-root 3 10)) |
||
(rf (coerce r 'float))) |
(rf (coerce r 'float))) |
||
(print (* r r r )) |
(print (* r r r )) |
||
(print (* rf rf rf)))</ |
(print (* rf rf rf)))</syntaxhighlight> |
||
produces the following output. |
produces the following output. |
||
Line 1,075: | Line 1,623: | ||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">import std.stdio, std.math; |
||
real nthroot(in int n, in real A, in real p=0.001) pure nothrow { |
real nthroot(in int n, in real A, in real p=0.001) pure nothrow { |
||
Line 1,087: | Line 1,635: | ||
writeln(nthroot(10, 7131.5 ^^ 10)); |
writeln(nthroot(10, 7131.5 ^^ 10)); |
||
writeln(nthroot(6, 64)); |
writeln(nthroot(6, 64)); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>7131.5 |
<pre>7131.5 |
||
2</pre> |
2</pre> |
||
=={{header|Dart}}== |
|||
<syntaxhighlight lang="dart">import 'dart:math' show pow; |
|||
num nroot(num value, num degree) { |
|||
return pow(value, (1 / degree)); |
|||
} |
|||
void main() { |
|||
int n = 15; |
|||
num x = pow(-3.14159, 15); |
|||
print('root($n, $x) = ${nroot(n, x)}'); |
|||
}</syntaxhighlight> |
|||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
< |
<syntaxhighlight lang="delphi"> |
||
USES |
USES |
||
Math; |
Math; |
||
Line 1,109: | Line 1,670: | ||
Result := x_p; |
Result := x_p; |
||
end; |
end; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|E}}== |
=={{header|E}}== |
||
Line 1,117: | Line 1,678: | ||
(Disclaimer: This was not written by a numerics expert; there may be reasons this is a bad idea. Also, it might be that cycles are always of length 2, which would reduce the amount of calculation needed by 2/3.) |
(Disclaimer: This was not written by a numerics expert; there may be reasons this is a bad idea. Also, it might be that cycles are always of length 2, which would reduce the amount of calculation needed by 2/3.) |
||
< |
<syntaxhighlight lang="e">def nthroot(n, x) { |
||
require(n > 1 && x > 0) |
require(n > 1 && x > 0) |
||
def np := n - 1 |
def np := n - 1 |
||
Line 1,128: | Line 1,689: | ||
} |
} |
||
return g1 |
return g1 |
||
}</ |
}</syntaxhighlight> |
||
=={{header|EasyLang}}== |
=={{header|EasyLang}}== |
||
<syntaxhighlight lang="text"> |
|||
<lang>func power x n . r . |
|||
func power x n . |
|||
r = 1 |
|||
for i = 1 to n |
|||
r *= x |
|||
. |
|||
. |
|||
return r |
|||
. |
. |
||
func nth_root x n |
func nth_root x n . |
||
r = 2 |
r = 2 |
||
repeat |
repeat |
||
p = power r (n - 1) |
|||
d = (x / p - r) / n |
d = (x / p - r) / n |
||
r += d |
r += d |
||
until abs d < 0.0001 |
until abs d < 0.0001 |
||
. |
. |
||
return r |
|||
. |
. |
||
numfmt 4 0 |
|||
call power 3.1416 10 x |
|||
x = power 3.1416 10 |
|||
call nth_root x 10 r |
|||
print nth_root x 10 |
|||
numb_fmt 0 4 |
|||
</syntaxhighlight> |
|||
print r</lang> |
|||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
{{trans|Erlang}} |
{{trans|Erlang}} |
||
< |
<syntaxhighlight lang="elixir">defmodule RC do |
||
def nth_root(n, x, precision \\ 1.0e-5) do |
def nth_root(n, x, precision \\ 1.0e-5) do |
||
f = fn(prev) -> ((n - 1) * prev + x / :math.pow(prev, (n-1))) / n end |
f = fn(prev) -> ((n - 1) * prev + x / :math.pow(prev, (n-1))) / n end |
||
Line 1,166: | Line 1,730: | ||
Enum.each([{2, 2}, {4, 81}, {10, 1024}, {1/2, 7}], fn {n, x} -> |
Enum.each([{2, 2}, {4, 81}, {10, 1024}, {1/2, 7}], fn {n, x} -> |
||
IO.puts "#{n} root of #{x} is #{RC.nth_root(n, x)}" |
IO.puts "#{n} root of #{x} is #{RC.nth_root(n, x)}" |
||
end)</ |
end)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,178: | Line 1,742: | ||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
Done by finding the fixed point of a function, which aims to find a value of <var>x</var> for which <var>f(x)=x</var>: |
Done by finding the fixed point of a function, which aims to find a value of <var>x</var> for which <var>f(x)=x</var>: |
||
< |
<syntaxhighlight lang="erlang">fixed_point(F, Guess, Tolerance) -> |
||
fixed_point(F, Guess, Tolerance, F(Guess)). |
fixed_point(F, Guess, Tolerance, F(Guess)). |
||
fixed_point(_, Guess, Tolerance, Next) when abs(Guess - Next) < Tolerance -> |
fixed_point(_, Guess, Tolerance, Next) when abs(Guess - Next) < Tolerance -> |
||
Next; |
Next; |
||
fixed_point(F, _, Tolerance, Next) -> |
fixed_point(F, _, Tolerance, Next) -> |
||
fixed_point(F, Next, Tolerance, F(Next)).</ |
fixed_point(F, Next, Tolerance, F(Next)).</syntaxhighlight> |
||
The nth root function algorithm defined on the wikipedia page linked above can advantage of this: |
The nth root function algorithm defined on the wikipedia page linked above can advantage of this: |
||
< |
<syntaxhighlight lang="erlang">nth_root(N, X) -> nth_root(N, X, 1.0e-5). |
||
nth_root(N, X, Precision) -> |
nth_root(N, X, Precision) -> |
||
F = fun(Prev) -> ((N - 1) * Prev + X / math:pow(Prev, (N-1))) / N end, |
F = fun(Prev) -> ((N - 1) * Prev + X / math:pow(Prev, (N-1))) / N end, |
||
fixed_point(F, X, Precision).</ |
fixed_point(F, X, Precision).</syntaxhighlight> |
||
=={{header|Excel}}== |
=={{header|Excel}}== |
||
Line 1,194: | Line 1,758: | ||
Beside the obvious; |
Beside the obvious; |
||
< |
<syntaxhighlight lang="excel">=A1^(1/B1)</syntaxhighlight> |
||
*Cell A1 is the base. |
*Cell A1 is the base. |
||
*Cell B1 is the exponent. |
*Cell B1 is the exponent. |
||
Line 1,246: | Line 1,810: | ||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
< |
<syntaxhighlight lang="fsharp"> |
||
let nthroot n A = |
let nthroot n A = |
||
let rec f x = |
let rec f x = |
||
Line 1,268: | Line 1,832: | ||
printf "%A" (nthroot n A) |
printf "%A" (nthroot n A) |
||
0 |
0 |
||
</syntaxhighlight> |
|||
</lang> |
|||
Compiled using <em>fsc nthroot.fs</em> example output:<pre> |
Compiled using <em>fsc nthroot.fs</em> example output:<pre> |
||
Line 1,276: | Line 1,840: | ||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
{{trans|Forth}} |
{{trans|Forth}} |
||
< |
<syntaxhighlight lang="factor">USING: kernel locals math math.functions prettyprint ; |
||
:: th-root ( a n -- a^1/n ) |
:: th-root ( a n -- a^1/n ) |
||
Line 1,287: | Line 1,851: | ||
34 5 th-root . ! 2.024397458499888 |
34 5 th-root . ! 2.024397458499888 |
||
34 5 recip ^ . ! 2.024397458499888</ |
34 5 recip ^ . ! 2.024397458499888</syntaxhighlight> |
||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
< |
<syntaxhighlight lang="forth">: th-root { F: a F: n -- a^1/n } |
||
a |
a |
||
begin |
begin |
||
Line 1,300: | Line 1,864: | ||
34e 5e th-root f. \ 2.02439745849989 |
34e 5e th-root f. \ 2.02439745849989 |
||
34e 5e 1/f f** f. \ 2.02439745849989</ |
34e 5e 1/f f** f. \ 2.02439745849989</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
< |
<syntaxhighlight lang="fortran">program NthRootTest |
||
implicit none |
implicit none |
||
Line 1,344: | Line 1,908: | ||
end function nthroot |
end function nthroot |
||
end program NthRootTest</ |
end program NthRootTest</syntaxhighlight> |
||
=={{header|FreeBASIC}}== |
|||
<lang freebasic>' version 14-01-2019 |
|||
' compile with: fbc -s console |
|||
Function nth_root(n As Integer, number As Double) As Double |
|||
Dim As Double a1 = number / n, a2 , a3 |
|||
Do |
|||
a3 = Abs(a2 - a1) |
|||
a2 = ((n -1) * a1 + number / a1 ^ (n -1)) / n |
|||
Swap a1, a2 |
|||
Loop Until Abs(a2 - a1) = a3 |
|||
Return a1 |
|||
End Function |
|||
' ------=< MAIN >=------ |
|||
Dim As UInteger n |
|||
Dim As Double tmp |
|||
Print |
|||
Print " n 5643 ^ 1 / n nth_root ^ n" |
|||
Print " ------------------------------------" |
|||
For n = 3 To 11 Step 2 |
|||
tmp = nth_root(n, 5643) |
|||
Print Using " ### ###.######## ####.########"; n; tmp; tmp ^ n |
|||
Next |
|||
Print |
|||
For n = 25 To 125 Step 25 |
|||
tmp = nth_root(n, 5643) |
|||
Print Using " ### ###.######## ####.########"; n; tmp; tmp ^ n |
|||
Next |
|||
' empty keyboard buffer |
|||
While Inkey <> "" : Wend |
|||
Print : Print "hit any key to end program" |
|||
Sleep |
|||
End</lang> |
|||
{{out}} |
|||
<pre> n 5643 ^ 1 / n nth_root ^ n |
|||
------------------------------------ |
|||
3 17.80341642 5643.00000000 |
|||
5 5.62732516 5643.00000000 |
|||
7 3.43502583 5643.00000000 |
|||
9 2.61116581 5643.00000000 |
|||
11 2.19303907 5643.00000000 |
|||
25 1.41273402 5643.00000000 |
|||
50 1.18858488 5643.00000000 |
|||
75 1.12207047 5643.00000000 |
|||
100 1.09022240 5643.00000000 |
|||
125 1.07154911 5643.00000000</pre> |
|||
=={{header|FutureBasic}}== |
|||
<lang futurebasic> |
|||
include "ConsoleWindow" |
|||
def tab 8 |
|||
local fn NthRoot( root as long, a as long, precision as double ) as double |
|||
dim as double x0, x1 |
|||
x0 = a : x1 = a /root |
|||
while ( abs( x1 - x0 ) > precision ) |
|||
x0 = x1 |
|||
x1 = ( ( root -1.0 ) * x1 + a / x1 ^ ( root -1.0 ) ) /root |
|||
wend |
|||
end fn = x1 |
|||
print " 125th Root of 5643 Precision .001", using "#.###############"; fn NthRoot( 125, 5642, 0.001 ) |
|||
print " 125th Root of 5643 Precision .001", using "#.###############"; fn NthRoot( 125, 5642, 0.001 ) |
|||
print " 125th Root of 5643 Precision .00001", using "#.###############"; fn NthRoot( 125, 5642, 0.00001 ) |
|||
print " Cube Root of 27 Precision .00001", using "#.###############"; fn NthRoot( 3, 27, 0.00001 ) |
|||
print "Square Root of 2 Precision .00001", using "#.###############"; fn NthRoot( 2, 2, 0.00001 ) |
|||
print "Square Root of 2 Precision .00001", using "#.###############"; sqr(2) // Processor floating point calc deviation |
|||
print " 10th Root of 1024 Precision .00001", using "#.###############"; fn NthRoot( 10, 1024, 0.00001 ) |
|||
print " 5th Root of 34 Precision .00001", using "#.###############"; fn NthRoot( 5, 34, 0.00001 ) |
|||
</lang> |
|||
Output: |
|||
<pre> |
|||
125th Root of 5643 Precision .001 1.071559602191682 |
|||
125th Root of 5643 Precision .001 1.071559602191682 |
|||
125th Root of 5643 Precision .00001 1.071547591944772 |
|||
Cube Root of 27 Precision .00001 3.000000000000002 |
|||
Square Root of 2 Precision .00001 1.414213562374690 |
|||
Square Root of 2 Precision .00001 1.414213562373095 |
|||
10th Root of 1024 Precision .00001 2.000000000000000 |
|||
5th Root of 34 Precision .00001 2.024397458499885 |
|||
</pre> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">func root(a float64, n int) float64 { |
||
n1 := n - 1 |
n1 := n - 1 |
||
n1f, rn := float64(n1), 1/float64(n) |
n1f, rn := float64(n1), 1/float64(n) |
||
Line 1,459: | Line 1,929: | ||
} |
} |
||
return x |
return x |
||
}</ |
}</syntaxhighlight> |
||
The above version is for 64 bit wide floating point numbers. The following uses `math/big` Float to implement this same function with 256 bits of precision. |
The above version is for 64 bit wide floating point numbers. The following uses `math/big` Float to implement this same function with 256 bits of precision. |
||
Line 1,465: | Line 1,935: | ||
''A set of wrapper functions around the somewhat muddled big math library functions is used to make the main function more readable, and also it was necessary to create a power function (Exp) as the library also lacks this function.'' '''The exponent in the limit must be at least one less than the number of bits of precision of the input value or the function will enter an infinite loop!''' |
''A set of wrapper functions around the somewhat muddled big math library functions is used to make the main function more readable, and also it was necessary to create a power function (Exp) as the library also lacks this function.'' '''The exponent in the limit must be at least one less than the number of bits of precision of the input value or the function will enter an infinite loop!''' |
||
<syntaxhighlight lang="go"> |
|||
<lang go> |
|||
import "math/big" |
import "math/big" |
||
Line 1,531: | Line 2,001: | ||
return x.Cmp(y) == -1 |
return x.Cmp(y) == -1 |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
Solution: |
Solution: |
||
< |
<syntaxhighlight lang="groovy">import static Constants.tolerance |
||
import static java.math.RoundingMode.HALF_UP |
import static java.math.RoundingMode.HALF_UP |
||
Line 1,548: | Line 2,018: | ||
(xNew as BigDecimal).setScale(7, HALF_UP) |
(xNew as BigDecimal).setScale(7, HALF_UP) |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Test: |
Test: |
||
< |
<syntaxhighlight lang="groovy">class Constants { |
||
static final tolerance = 0.00001 |
static final tolerance = 0.00001 |
||
} |
} |
||
Line 1,571: | Line 2,041: | ||
it.b, it.n, r, it.r) |
it.b, it.n, r, it.r) |
||
assert (r - it.r).abs() <= tolerance |
assert (r - it.r).abs() <= tolerance |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
Line 1,584: | Line 2,054: | ||
Function exits when there's no difference between two successive values. |
Function exits when there's no difference between two successive values. |
||
< |
<syntaxhighlight lang="haskell">n `nthRoot` x = fst $ until (uncurry(==)) (\(_,x0) -> (x0,((n-1)*x0+x/x0**(n-1))/n)) (x,x/n)</syntaxhighlight> |
||
Use: |
Use: |
||
<pre>*Main> 2 `nthRoot` 2 |
<pre>*Main> 2 `nthRoot` 2 |
||
Line 1,601: | Line 2,071: | ||
Or, in applicative terms, with formatted output: |
Or, in applicative terms, with formatted output: |
||
< |
<syntaxhighlight lang="haskell">nthRoot :: Double -> Double -> Double |
||
nthRoot n x = |
nthRoot n x = |
||
fst $ |
fst $ |
||
Line 1,628: | Line 2,098: | ||
rjust n c = drop . length <*> (replicate n c ++) |
rjust n c = drop . length <*> (replicate n c ++) |
||
in unlines $ |
in unlines $ |
||
s : fmap (((++) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs</ |
s : fmap (((++) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>Nth roots: |
<pre>Nth roots: |
||
Line 1,637: | Line 2,107: | ||
=={{header|HicEst}}== |
=={{header|HicEst}}== |
||
< |
<syntaxhighlight lang="hicest">WRITE(Messagebox) NthRoot(5, 34) |
||
WRITE(Messagebox) NthRoot(10, 7131.5^10) |
WRITE(Messagebox) NthRoot(10, 7131.5^10) |
||
Line 1,655: | Line 2,125: | ||
WRITE(Messagebox, Name) 'Cannot solve problem for:', prec, n, A |
WRITE(Messagebox, Name) 'Cannot solve problem for:', prec, n, A |
||
END</ |
END</syntaxhighlight> |
||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
All Icon/Unicon reals are double precision. |
All Icon/Unicon reals are double precision. |
||
< |
<syntaxhighlight lang="icon">procedure main() |
||
showroot(125,3) |
showroot(125,3) |
||
showroot(27,3) |
showroot(27,3) |
||
Line 1,681: | Line 2,151: | ||
end |
end |
||
link printf</ |
link printf</syntaxhighlight> |
||
Output:<pre>3-th root of 125 = 5.0 |
Output:<pre>3-th root of 125 = 5.0 |
||
Line 1,696: | Line 2,166: | ||
But, since the [[Talk:Nth_root_algorithm#Comparison_to_Non-integer_Exponentiation|talk page discourages]] using built-in facilities, here is a reimplementation, using the [[#E|E]] algorithm: |
But, since the [[Talk:Nth_root_algorithm#Comparison_to_Non-integer_Exponentiation|talk page discourages]] using built-in facilities, here is a reimplementation, using the [[#E|E]] algorithm: |
||
< |
<syntaxhighlight lang="j"> '`N X NP' =. (0 { [)`(1 { [)`(2 { [) |
||
iter =. N %~ (NP * ]) + X % ] ^ NP |
iter =. N %~ (NP * ]) + X % ] ^ NP |
||
nth_root =: (, , _1+[) iter^:_ f. ] |
nth_root =: (, , _1+[) iter^:_ f. ] |
||
10 nth_root 7131.5^10 |
10 nth_root 7131.5^10 |
||
7131.5</ |
7131.5</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{trans|Fortran}} |
{{trans|Fortran}} |
||
< |
<syntaxhighlight lang="java">public static double nthroot(int n, double A) { |
||
return nthroot(n, A, .001); |
return nthroot(n, A, .001); |
||
} |
} |
||
Line 1,721: | Line 2,191: | ||
} |
} |
||
return x; |
return x; |
||
}</ |
}</syntaxhighlight> |
||
{{trans|E}} |
{{trans|E}} |
||
< |
<syntaxhighlight lang="java">public static double nthroot(int n, double x) { |
||
assert (n > 1 && x > 0); |
assert (n > 1 && x > 0); |
||
int np = n - 1; |
int np = n - 1; |
||
Line 1,737: | Line 2,207: | ||
private static double iter(double g, int np, int n, double x) { |
private static double iter(double g, int np, int n, double x) { |
||
return (np * g + x / Math.pow(g, np)) / n; |
return (np * g + x / Math.pow(g, np)) / n; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
Gives the ''n'':nth root of ''num'', with precision ''prec''. (''n'' defaults to 2 [e.g. sqrt], ''prec'' defaults to 12.) |
Gives the ''n'':nth root of ''num'', with precision ''prec''. (''n'' defaults to 2 [e.g. sqrt], ''prec'' defaults to 12.) |
||
< |
<syntaxhighlight lang="javascript">function nthRoot(num, nArg, precArg) { |
||
var n = nArg || 2; |
var n = nArg || 2; |
||
var prec = precArg || 12; |
var prec = precArg || 12; |
||
Line 1,752: | Line 2,222: | ||
return x; |
return x; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|jq}}== |
=={{header|jq}}== |
||
< |
<syntaxhighlight lang="jq"># An iterative algorithm for finding: self ^ (1/n) to the given |
||
# absolute precision if "precision" > 0, or to within the precision |
# absolute precision if "precision" > 0, or to within the precision |
||
# allowed by IEEE 754 64-bit numbers. |
# allowed by IEEE 754 64-bit numbers. |
||
Line 1,785: | Line 2,255: | ||
else [., ., (./n), n, 0] | _iterate |
else [., ., (./n), n, 0] | _iterate |
||
end |
end |
||
;</ |
;</syntaxhighlight> |
||
'''Example''': |
'''Example''': |
||
Compare the results of iterative_nth_root and nth_root implemented using builtins |
Compare the results of iterative_nth_root and nth_root implemented using builtins |
||
< |
<syntaxhighlight lang="jq">def demo(x): |
||
def nth_root(n): log / n | exp; |
def nth_root(n): log / n | exp; |
||
def lpad(n): tostring | (n - length) * " " + .; |
def lpad(n): tostring | (n - length) * " " + .; |
||
Line 1,797: | Line 2,267: | ||
# 5^m for various values of n: |
# 5^m for various values of n: |
||
"5^(1/ n): builtin precision=1e-10 precision=0", |
"5^(1/ n): builtin precision=1e-10 precision=0", |
||
( (1,-5,-3,-1,1,3,5,1000,10000) | demo(5))</ |
( (1,-5,-3,-1,1,3,5,1000,10000) | demo(5))</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
< |
<syntaxhighlight lang="sh">$ jq -n -r -f nth_root_machine_precision.jq |
||
5^(1/ n): builtin precision=1e-10 precision=0 |
5^(1/ n): builtin precision=1e-10 precision=0 |
||
5^(1/ 1): 4.999999999999999 vs 5 vs 5 |
5^(1/ 1): 4.999999999999999 vs 5 vs 5 |
||
Line 1,810: | Line 2,280: | ||
5^(1/ 1000): 1.0016107337527294 vs 1.0016107337527294 vs 1.0016107337527294 |
5^(1/ 1000): 1.0016107337527294 vs 1.0016107337527294 vs 1.0016107337527294 |
||
5^(1/10000): 1.0001609567433902 vs 1.0001609567433902 vs 1.0001609567433902 |
5^(1/10000): 1.0001609567433902 vs 1.0001609567433902 vs 1.0001609567433902 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Line 1,816: | Line 2,286: | ||
Julia has a built-in exponentiation function <code>A^(1 / n)</code>, but the specification calls for us to use Newton's method (which we iterate until the limits of machine precision are reached): |
Julia has a built-in exponentiation function <code>A^(1 / n)</code>, but the specification calls for us to use Newton's method (which we iterate until the limits of machine precision are reached): |
||
< |
<syntaxhighlight lang="julia">function nthroot(n::Integer, r::Real) |
||
r < 0 || n == 0 && throw(DomainError()) |
r < 0 || n == 0 && throw(DomainError()) |
||
n < 0 && return 1 / nthroot(-n, r) |
n < 0 && return 1 / nthroot(-n, r) |
||
Line 1,832: | Line 2,302: | ||
@show nthroot.(-5:2:5, 5.0) |
@show nthroot.(-5:2:5, 5.0) |
||
@show nthroot.(-5:2:5, 5.0) - 5.0 .^ (1 ./ (-5:2:5))</ |
@show nthroot.(-5:2:5, 5.0) - 5.0 .^ (1 ./ (-5:2:5))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,840: | Line 2,310: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|E}} |
{{trans|E}} |
||
< |
<syntaxhighlight lang="scala">// version 1.0.6 |
||
fun nthRoot(x: Double, n: Int): Double { |
fun nthRoot(x: Double, n: Int): Double { |
||
Line 1,860: | Line 2,330: | ||
for (number in numbers) |
for (number in numbers) |
||
println("${number.first} ^ 1/${number.second}\t = ${nthRoot(number.first, number.second)}") |
println("${number.first} ^ 1/${number.second}\t = ${nthRoot(number.first, number.second)}") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,871: | Line 2,341: | ||
=={{header|Lambdatalk}}== |
=={{header|Lambdatalk}}== |
||
Translation of Scheme |
Translation of Scheme |
||
<syntaxhighlight lang="scheme"> |
|||
<lang Scheme> |
|||
{def root |
{def root |
||
{def good-enough? {lambda {next guess tol} |
{def good-enough? {lambda {next guess tol} |
||
Line 1,894: | Line 2,364: | ||
{root {pow 2 10} 10 0.001} |
{root {pow 2 10} 10 0.001} |
||
-> 2.000047868581671 |
-> 2.000047868581671 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|langur}}== |
=={{header|langur}}== |
||
Langur has a root operator. Here, we show use of both the root operator and an nth root function. |
Langur has a root operator. Here, we show use of both the root operator and an nth root function. |
||
{{works with|langur|0.8}} |
|||
{{trans|D}} |
{{trans|D}} |
||
< |
<syntaxhighlight lang="langur">writeln "operator" |
||
writeln |
writeln (7131.5 ^ 10) ^/ 10 |
||
writeln 64 ^/ 6 |
writeln 64 ^/ 6 |
||
writeln() |
writeln() |
||
val .nthroot = fn(.n, .A, .p) { |
|||
# To make the example from the D language work, we set a low maximum for the number of digits after a decimal point in division. |
|||
mode divMaxScale = 7 |
|||
val .nthroot = f(.n, .A, .p) { |
|||
var .x = [.A, .A / .n] |
var .x = [.A, .A / .n] |
||
while abs(.x[2]-.x[1]) > .p { |
while abs(.x[2]-.x[1]) > .p { |
||
Line 1,917: | Line 2,383: | ||
} |
} |
||
# To make the example from the D language work, we set a low maximum for the number of digits after a decimal point in division. |
|||
writeln "calculation" |
|||
mode divMaxScale = 7 |
|||
writeln "function" |
|||
writeln .nthroot(10, 7131.5 ^ 10, 0.001) |
writeln .nthroot(10, 7131.5 ^ 10, 0.001) |
||
writeln .nthroot(6, 64, 0.001)</ |
writeln .nthroot(6, 64, 0.001)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,926: | Line 2,395: | ||
2 |
2 |
||
function |
|||
calculation |
|||
7131.5 |
7131.5 |
||
2 |
2 |
||
</pre> |
</pre> |
||
=={{header|Liberty BASIC}}== |
|||
<lang lb> |
|||
print "First estimate is: ", using( "#.###############", NthRoot( 125, 5642, 0.001 )); |
|||
print " ... and better is: ", using( "#.###############", NthRoot( 125, 5642, 0.00001)) |
|||
print "125'th root of 5642 by LB's exponentiation operator is "; using( "#.###############", 5642^(1 /125)) |
|||
print "27^(1 / 3)", using( "#.###############", NthRoot( 3, 27, 0.00001)) |
|||
print "2^(1 / 2)", using( "#.###############", NthRoot( 2, 2, 0.00001)) |
|||
print "1024^(1 /10)", using( "#.###############", NthRoot( 10, 1024, 0.00001)) |
|||
wait |
|||
function NthRoot( n, A, p) |
|||
x( 0) =A |
|||
x( 1) =A /n |
|||
while abs( x( 1) -x( 0)) >p |
|||
x( 0) =x( 1) |
|||
x( 1) =( ( n -1.0) *x( 1) +A /x( 1)^( n -1.0)) /n |
|||
wend |
|||
NthRoot =x( 1) |
|||
end function |
|||
end |
|||
</lang> |
|||
First estimate is: 1.071559602191682 ... and better is: 1.071547591944771 |
|||
125'th root of 5642 by LB's exponentiation operator is 1.071547591944767 |
|||
27^(1 / 3) 3.000000000000002 |
|||
2^(1 / 2) 1.414213562374690 |
|||
1024^(1 /10) 2.000000000000000 |
|||
=={{header|Lingo}}== |
=={{header|Lingo}}== |
||
< |
<syntaxhighlight lang="lingo">on nthRoot (x, root) |
||
return power(x, 1.0/root) |
return power(x, 1.0/root) |
||
end</ |
end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="lingo">the floatPrecision = 8 -- only about display/string cast of floats |
||
put nthRoot(4, 4) |
put nthRoot(4, 4) |
||
-- 1.41421356</ |
-- 1.41421356</syntaxhighlight> |
||
=={{header|Logo}}== |
=={{header|Logo}}== |
||
< |
<syntaxhighlight lang="logo">to about :a :b |
||
output and [:a - :b < 1e-5] [:a - :b > -1e-5] |
output and [:a - :b < 1e-5] [:a - :b > -1e-5] |
||
end |
end |
||
Line 1,981: | Line 2,419: | ||
end |
end |
||
show root 5 34 ; 2.02439745849989</ |
show root 5 34 ; 2.02439745849989</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
<syntaxhighlight lang="lua"> |
|||
<lang Lua> |
|||
function nroot(root, num) |
function nroot(root, num) |
||
return num^(1/root) |
return num^(1/root) |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
Line 2,017: | Line 2,455: | ||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module Checkit { |
Module Checkit { |
||
Function Root (a, n%, d as double=1.e-4) { |
Function Root (a, n%, d as double=1.e-4) { |
||
Line 2,042: | Line 2,480: | ||
} |
} |
||
Checkit |
Checkit |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
The <code>root</code> command performs this task. |
The <code>root</code> command performs this task. |
||
<syntaxhighlight lang="maple"> |
|||
<lang Maple> |
|||
root(1728, 3); |
root(1728, 3); |
||
Line 2,053: | Line 2,491: | ||
root(2.0, 2); |
root(2.0, 2); |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
Line 2,065: | Line 2,503: | ||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
<lang |
<syntaxhighlight lang="mathematica">Root[A,n]</syntaxhighlight> |
||
=={{header|MATLAB}}== |
=={{header|MATLAB}}== |
||
< |
<syntaxhighlight lang="matlab">function answer = nthRoot(number,root) |
||
format long |
format long |
||
Line 2,080: | Line 2,518: | ||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
Sample Output: |
Sample Output: |
||
< |
<syntaxhighlight lang="matlab">>> nthRoot(2,2) |
||
ans = |
ans = |
||
1.414213562373095</ |
1.414213562373095</syntaxhighlight> |
||
=={{header|Maxima}}== |
=={{header|Maxima}}== |
||
< |
<syntaxhighlight lang="maxima">nth_root(a, n) := block( |
||
[x, y, d, p: fpprec], |
[x, y, d, p: fpprec], |
||
fpprec: p + 10, |
fpprec: p + 10, |
||
Line 2,102: | Line 2,540: | ||
fpprec: p, |
fpprec: p, |
||
bfloat(y) |
bfloat(y) |
||
)$</ |
)$</syntaxhighlight> |
||
=={{header|Metafont}}== |
=={{header|Metafont}}== |
||
Metafont does not use IEEE floating point and we can't go beyond 0.0001 or it will loop forever. |
Metafont does not use IEEE floating point and we can't go beyond 0.0001 or it will loop forever. |
||
< |
<syntaxhighlight lang="metafont">vardef mnthroot(expr n, A) = |
||
x0 := A / n; |
x0 := A / n; |
||
m := n - 1; |
m := n - 1; |
||
Line 2,122: | Line 2,560: | ||
show 0.5 nthroot 7; % 49.00528 |
show 0.5 nthroot 7; % 49.00528 |
||
bye</ |
bye</syntaxhighlight> |
||
=={{header|МК-61/52}}== |
=={{header|МК-61/52}}== |
||
<lang>1/x <-> x^y С/П</ |
<syntaxhighlight lang="text">1/x <-> x^y С/П</syntaxhighlight> |
||
Instruction: ''number'' ^ ''degree'' В/О С/П |
Instruction: ''number'' ^ ''degree'' В/О С/П |
||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
{{trans|REXX}} |
{{trans|REXX}} |
||
< |
<syntaxhighlight lang="netrexx"> |
||
/*NetRexx program to calculate the Nth root of X, with DIGS accuracy. */ |
/*NetRexx program to calculate the Nth root of X, with DIGS accuracy. */ |
||
class nth_root |
class nth_root |
||
Line 2,210: | Line 2,648: | ||
return _/1 /*normalize the number to digs. */ |
return _/1 /*normalize the number to digs. */ |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|NewLISP}}== |
=={{header|NewLISP}}== |
||
< |
<syntaxhighlight lang="newlisp">(define (nth-root n a) |
||
(let ((x1 a) |
(let ((x1 a) |
||
(x2 (div a n))) |
(x2 (div a n))) |
||
Line 2,223: | Line 2,661: | ||
(div a (pow x1 (- n 1)))) |
(div a (pow x1 (- n 1)))) |
||
n))) |
n))) |
||
x2))</ |
x2))</syntaxhighlight> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">import math |
||
proc nthRoot(a: float; n: int): float = |
proc nthRoot(a: float; n: int): float = |
||
Line 2,238: | Line 2,676: | ||
echo nthRoot(34.0, 5) |
echo nthRoot(34.0, 5) |
||
echo nthRoot(42.0, 10) |
echo nthRoot(42.0, 10) |
||
echo nthRoot(5.0, 2)</ |
echo nthRoot(5.0, 2)</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>2.024397458499885 |
<pre>2.024397458499885 |
||
1.453198460282268 |
1.453198460282268 |
||
2.23606797749979</pre> |
2.23606797749979</pre> |
||
=={{header|Nu}}== |
|||
<syntaxhighlight lang="nu"> |
|||
def "math root" [n] {$in ** (1 / $n)} |
|||
1..10 | each {|it| |
|||
1..10 | reduce --fold {index: $it} {|root acc| |
|||
$acc | insert $"root ($root)" ($it | math root $root | into string --decimals 4 ) |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
╭──────┬───────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬─────────┬─────────┬──────────╮ |
|||
│ # │ root 1 │ root 2 │ root 3 │ root 4 │ root 5 │ root 6 │ root 7 │ root 8 │ root 9 │ root 10 │ |
|||
├──────┼───────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼─────────┼─────────┼──────────┤ |
|||
│ 1 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ |
|||
│ 2 │ 2.0000 │ 1.4142 │ 1.2599 │ 1.1892 │ 1.1487 │ 1.1225 │ 1.1041 │ 1.0905 │ 1.0801 │ 1.0718 │ |
|||
│ 3 │ 3.0000 │ 1.7321 │ 1.4422 │ 1.3161 │ 1.2457 │ 1.2009 │ 1.1699 │ 1.1472 │ 1.1298 │ 1.1161 │ |
|||
│ 4 │ 4.0000 │ 2.0000 │ 1.5874 │ 1.4142 │ 1.3195 │ 1.2599 │ 1.2190 │ 1.1892 │ 1.1665 │ 1.1487 │ |
|||
│ 5 │ 5.0000 │ 2.2361 │ 1.7100 │ 1.4953 │ 1.3797 │ 1.3077 │ 1.2585 │ 1.2228 │ 1.1958 │ 1.1746 │ |
|||
│ 6 │ 6.0000 │ 2.4495 │ 1.8171 │ 1.5651 │ 1.4310 │ 1.3480 │ 1.2917 │ 1.2510 │ 1.2203 │ 1.1962 │ |
|||
│ 7 │ 7.0000 │ 2.6458 │ 1.9129 │ 1.6266 │ 1.4758 │ 1.3831 │ 1.3205 │ 1.2754 │ 1.2414 │ 1.2148 │ |
|||
│ 8 │ 8.0000 │ 2.8284 │ 2.0000 │ 1.6818 │ 1.5157 │ 1.4142 │ 1.3459 │ 1.2968 │ 1.2599 │ 1.2311 │ |
|||
│ 9 │ 9.0000 │ 3.0000 │ 2.0801 │ 1.7321 │ 1.5518 │ 1.4422 │ 1.3687 │ 1.3161 │ 1.2765 │ 1.2457 │ |
|||
│ 10 │ 10.0000 │ 3.1623 │ 2.1544 │ 1.7783 │ 1.5849 │ 1.4678 │ 1.3895 │ 1.3335 │ 1.2915 │ 1.2589 │ |
|||
╰──────┴───────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴─────────┴─────────┴──────────╯ |
|||
</pre> |
|||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="objeck">class NthRoot { |
||
function : Main(args : String[]) ~ Nil { |
function : Main(args : String[]) ~ Nil { |
||
NthRoot(5, 34, .001)->PrintLine(); |
NthRoot(5, 34, .001)->PrintLine(); |
||
Line 2,263: | Line 2,729: | ||
return x[1]; |
return x[1]; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="ocaml">let nthroot ~n ~a ?(tol=0.001) () = |
||
let nf = float n in let nf1 = nf -. 1.0 in |
let nf = float n in let nf1 = nf -. 1.0 in |
||
let rec iter x = |
let rec iter x = |
||
Line 2,278: | Line 2,744: | ||
Printf.printf "%g\n" (nthroot 10 (7131.5 ** 10.0) ()); |
Printf.printf "%g\n" (nthroot 10 (7131.5 ** 10.0) ()); |
||
Printf.printf "%g\n" (nthroot 5 34.0 ()); |
Printf.printf "%g\n" (nthroot 5 34.0 ()); |
||
;;</ |
;;</syntaxhighlight> |
||
=={{header|Octave}}== |
=={{header|Octave}}== |
||
Octave has it's how <tt>nthroot</tt> function. |
Octave has it's how <tt>nthroot</tt> function. |
||
< |
<syntaxhighlight lang="octave"> |
||
r = A.^(1./n) |
r = A.^(1./n) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Here it is another implementation (after Tcl) |
Here it is another implementation (after Tcl) |
||
{{trans|Tcl}} |
{{trans|Tcl}} |
||
< |
<syntaxhighlight lang="octave">function r = m_nthroot(n, A) |
||
x0 = A / n; |
x0 = A / n; |
||
m = n - 1; |
m = n - 1; |
||
Line 2,300: | Line 2,766: | ||
x0 = x1; |
x0 = x1; |
||
endwhile |
endwhile |
||
endfunction</ |
endfunction</syntaxhighlight> |
||
Here is an more elegant way by computing the successive differences in an explicit way: |
Here is an more elegant way by computing the successive differences in an explicit way: |
||
< |
<syntaxhighlight lang="octave">function r = m_nthroot(n, A) |
||
r = A / n; |
r = A / n; |
||
m = n - 1; |
m = n - 1; |
||
Line 2,310: | Line 2,776: | ||
r+= d; |
r+= d; |
||
until (abs(d) < abs(r * 1e-9)) |
until (abs(d) < abs(r * 1e-9)) |
||
endfunction</ |
endfunction</syntaxhighlight> |
||
Show its usage and the built-in <tt>nthroot</tt> function |
Show its usage and the built-in <tt>nthroot</tt> function |
||
< |
<syntaxhighlight lang="octave">m_nthroot(10, 7131.5 .^ 10) |
||
nthroot(7131.5 .^ 10, 10) |
nthroot(7131.5 .^ 10, 10) |
||
m_nthroot(5, 34) |
m_nthroot(5, 34) |
||
nthroot(34, 5) |
nthroot(34, 5) |
||
m_nthroot(0.5, 7) |
m_nthroot(0.5, 7) |
||
nthroot(7, .5)</ |
nthroot(7, .5)</syntaxhighlight> |
||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
< |
<syntaxhighlight lang="oforth">Float method: nthroot(n) |
||
1.0 doWhile: [ self over n 1 - pow / over - n / tuck + swap 0.0 <> ] ;</ |
1.0 doWhile: [ self over n 1 - pow / over - n / tuck + swap 0.0 <> ] ;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,339: | Line 2,805: | ||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
< |
<syntaxhighlight lang="oz">declare |
||
fun {NthRoot NInt A} |
fun {NthRoot NInt A} |
||
N = {Int.toFloat NInt} |
N = {Int.toFloat NInt} |
||
Line 2,357: | Line 2,823: | ||
end |
end |
||
in |
in |
||
{Show {NthRoot 2 2.0}}</ |
{Show {NthRoot 2 2.0}}</syntaxhighlight> |
||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
< |
<syntaxhighlight lang="parigp">root(n,A)=A^(1/n);</syntaxhighlight> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
Line 2,367: | Line 2,833: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
{{trans|Tcl}} |
{{trans|Tcl}} |
||
< |
<syntaxhighlight lang="perl">use strict; |
||
sub nthroot ($$) |
sub nthroot ($$) |
||
Line 2,380: | Line 2,846: | ||
$x0 = $x1; |
$x0 = $x1; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="perl">print nthroot(5, 34), "\n"; |
||
print nthroot(10, 7131.5 ** 10), "\n"; |
print nthroot(10, 7131.5 ** 10), "\n"; |
||
print nthroot(0.5, 7), "\n";</ |
print nthroot(0.5, 7), "\n";</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Main loop copied from AWK, and as per C uses pow_() instead of power() since using the latter would make the whole exercise somewhat pointless. |
|||
{{trans|AWK}} |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
(main loop) |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
{{trans|C}} |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">pow_</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">)</span> |
|||
(use of pow_ instead of power)<br> |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
<lang Phix>function pow_(atom x, integer e) |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">e</span> <span style="color: #008080;">do</span> |
|||
atom r = 1 |
|||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">x</span> |
|||
for i=1 to e do |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
r *= x |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
return r |
|||
end function |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">nth_root</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">eps</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1e-15</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- relative accuracy</span> |
|||
function nth_root(atom y,n) |
|||
<span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
atom eps = 1e-15 -- relative accuracy |
|||
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
atom x = 1 |
|||
<span style="color: #000080;font-style:italic;">-- atom d = ( y / power(x,n-1) - x ) / n</span> |
|||
while 1 do |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span> <span style="color: #000000;">y</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">pow_</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">)</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">n</span> |
|||
-- atom d = ( y / power(x,n-1) - x ) / n |
|||
<span style="color: #000000;">x</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">d</span> |
|||
atom d = ( y / pow_(x,n-1) - x ) / n |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eps</span><span style="color: #0000FF;">*</span><span style="color: #000000;">x</span> <span style="color: #000080;font-style:italic;">-- absolute accuracy </span> |
|||
x += d |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">></span> <span style="color: #0000FF;">-</span><span style="color: #000000;">e</span> <span style="color: #008080;">and</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;"><</span> <span style="color: #000000;">e</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
atom e = eps*x -- absolute accuracy |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
if d > -e and d < e then exit end if |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">x</span> |
|||
end while |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
return {y,n,x,power(y,1/n)} |
|||
end function |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">yn</span><span style="color: #0000FF;">)</span> |
|||
?nth_root(1024,10) |
|||
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">yn</span> |
|||
?nth_root(27,3) |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"nth_root(%d,%d) = %.10g, builtin = %.10g\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nth_root</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)})</span> |
|||
?nth_root(2,2) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
?nth_root(5642,125) |
|||
<span style="color: #7060A8;">papply</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">1024</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">27</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">5642</span><span style="color: #0000FF;">,</span><span style="color: #000000;">125</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">4913</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">125</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1000000000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1000000000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">}},</span><span style="color: #000000;">test</span><span style="color: #0000FF;">)</span> |
|||
--?nth_root(7,0.5) -- needs power(), not pow_() |
|||
<!--</syntaxhighlight>--> |
|||
?nth_root(4913,3) |
|||
Note that a {7,0.5} test would need to use power() instead of pow_(). |
|||
?nth_root(8,3) |
|||
?nth_root(16,2) |
|||
?nth_root(16,4) |
|||
?nth_root(125,3) |
|||
?nth_root(1000000000,3) |
|||
?nth_root(1000000000,9)</lang> |
|||
{{out}} |
{{out}} |
||
Shows inputs and both the iterative and builtin results. |
|||
<pre> |
<pre> |
||
nth_root(1024,10) = 2, builtin = 2 |
|||
{1024,10,2,2} |
|||
nth_root(27,3) = 3, builtin = 3 |
|||
{27,3,3,3} |
|||
nth_root(2,2) = 1.414213562, builtin = 1.414213562 |
|||
nth_root(5642,125) = 1.071547592, builtin = 1.071547592 |
|||
nth_root(4913,3) = 17, builtin = 17 |
|||
{4913,3,17,17.0} |
|||
nth_root(8,3) = 2, builtin = 2 |
|||
{8,3,2,2} |
|||
nth_root(16,2) = 4, builtin = 4 |
|||
{16,2,4,4} |
|||
nth_root(16,4) = 2, builtin = 2 |
|||
{16,4,2,2} |
|||
nth_root(125,3) = 5, builtin = 5 |
|||
{125,3,5,5} |
|||
nth_root(1000000000,3) = 1000, builtin = 1000 |
|||
nth_root(1000000000,9) = 10, builtin = 10 |
|||
</pre> |
</pre> |
||
=={{header|Phixmonti}}== |
=={{header|Phixmonti}}== |
||
< |
<syntaxhighlight lang="phixmonti">def nthroot |
||
var n var y |
var n var y |
||
1e-15 var eps /# relative accuracy #/ |
1e-15 var eps /# relative accuracy #/ |
||
Line 2,467: | Line 2,926: | ||
"The " e "th root of " b " is " b 1 e / power " (" b e nthroot ")" 9 tolist |
"The " e "th root of " b " is " b 1 e / power " (" b e nthroot ")" 9 tolist |
||
printList drop nl |
printList drop nl |
||
endfor</ |
endfor</syntaxhighlight> |
||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
< |
<syntaxhighlight lang="php">function nthroot($number, $root, $p = P) |
||
{ |
{ |
||
$x[0] = $number; |
$x[0] = $number; |
||
Line 2,480: | Line 2,939: | ||
} |
} |
||
return $x[1]; |
return $x[1]; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Picat}}== |
|||
<syntaxhighlight lang="picat">go => |
|||
L = [[2,2], |
|||
[34,5], |
|||
[34**5,5], |
|||
[7131.5**10], |
|||
[7,0.5], |
|||
[1024,10], |
|||
[5642, 125] |
|||
], |
|||
foreach([A,N] in L) |
|||
R = nthroot(A,N), |
|||
printf("nthroot(%8w,%8w) %20w (check: %w)\n",A,N,R,A**(1/N)) |
|||
end, |
|||
nl. |
|||
% |
|||
% x^n = a |
|||
% |
|||
% Given a and n, find x (to Precision) |
|||
% |
|||
nthroot(A,N) = nthroot(A,N,0.000001). |
|||
nthroot(A,N,Precision) = X1 => |
|||
NF = N * 1.0, % float version of N |
|||
X0 = A / NF, |
|||
X1 = 1.0, |
|||
do |
|||
X0 := X1, |
|||
X1 := (1.0 / NF)*((NF - 1.0)*X0 + (A / (X0 ** (NF - 1)))) |
|||
while( abs(X0-X1) > Precision).</syntaxhighlight> |
|||
{{out}} |
|||
<pre>nthroot( 2, 2) 1.414213562373095 (check: 1.414213562373095) |
|||
nthroot( 34, 5) 2.024397458499885 (check: 2.024397458499885) |
|||
nthroot(45435424, 5) 34.0 (check: 34.000000000000007) |
|||
nthroot( 7, 0.5) 48.999999999999993 (check: 49.0) |
|||
nthroot( 1024, 10) 2.0 (check: 2.0) |
|||
nthroot( 5642, 125) 1.071547591944767 (check: 1.071547591944767)</pre> |
|||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(load "@lib/math.l") |
||
(de nthRoot (N A) |
(de nthRoot (N A) |
||
Line 2,499: | Line 2,998: | ||
(prinl (format (nthRoot 2 2.0) *Scl)) |
(prinl (format (nthRoot 2 2.0) *Scl)) |
||
(prinl (format (nthRoot 3 12.3) *Scl)) |
(prinl (format (nthRoot 3 12.3) *Scl)) |
||
(prinl (format (nthRoot 4 45.6) *Scl))</ |
(prinl (format (nthRoot 4 45.6) *Scl))</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>1.414214 |
<pre>1.414214 |
||
Line 2,506: | Line 3,005: | ||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
< |
<syntaxhighlight lang="pl/i">/* Finds the N-th root of the number A */ |
||
root: procedure (A, N) returns (float); |
root: procedure (A, N) returns (float); |
||
declare A float, N fixed binary; |
declare A float, N fixed binary; |
||
Line 2,518: | Line 3,017: | ||
end; |
end; |
||
return (xi); |
return (xi); |
||
end root;</ |
end root;</syntaxhighlight> |
||
Results: |
Results: |
||
<pre> |
<pre> |
||
Line 2,530: | Line 3,029: | ||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
This sample implementation does not use <code>[System.Math]</code> classes. |
This sample implementation does not use <code>[System.Math]</code> classes. |
||
< |
<syntaxhighlight lang="powershell">#NoTeS: This sample code does not validate inputs |
||
# Thus, if there are errors the 'scary' red-text |
# Thus, if there are errors the 'scary' red-text |
||
# error messages will appear. |
# error messages will appear. |
||
Line 2,568: | Line 3,067: | ||
((root 5 2)+1)/2 #Extra: Computes the golden ratio |
((root 5 2)+1)/2 #Extra: Computes the golden ratio |
||
((root 5 2)-1)/2</ |
((root 5 2)-1)/2</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>PS> .\NTH.PS1 |
<pre>PS> .\NTH.PS1 |
||
Line 2,582: | Line 3,081: | ||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
Uses integer math, though via scaling, it can approximate non-integral roots to arbitrary precision. |
Uses integer math, though via scaling, it can approximate non-integral roots to arbitrary precision. |
||
<syntaxhighlight lang="prolog"> |
|||
<lang Prolog> |
|||
iroot(_, 0, 0) :- !. |
iroot(_, 0, 0) :- !. |
||
iroot(M, N, R) :- |
iroot(M, N, R) :- |
||
Line 2,604: | Line 3,103: | ||
newton(2, A, X0, X1) :- X1 is (X0 + A div X0) >> 1, !. % fast special case |
newton(2, A, X0, X1) :- X1 is (X0 + A div X0) >> 1, !. % fast special case |
||
newton(N, A, X0, X1) :- X1 is ((N - 1)*X0 + A div X0**(N - 1)) div N. |
newton(N, A, X0, X1) :- X1 is ((N - 1)*X0 + A div X0**(N - 1)) div N. |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,627: | Line 3,126: | ||
X = -3. |
X = -3. |
||
</pre> |
</pre> |
||
=={{header|PureBasic}}== |
|||
<lang PureBasic>#Def_p=0.001 |
|||
Procedure.d Nth_root(n.i, A.d, p.d=#Def_p) |
|||
Protected Dim x.d(1) |
|||
x(0)=A: x(1)=A/n |
|||
While Abs(x(1)-x(0))>p |
|||
x(0)=x(1) |
|||
x(1)=((n-1.0)*x(1)+A/Pow(x(1),n-1.0))/n |
|||
Wend |
|||
ProcedureReturn x(1) |
|||
EndProcedure |
|||
;////////////////////////////// |
|||
Debug "125'th root of 5642 is" |
|||
Debug Pow(5642,1/125) |
|||
Debug "First estimate is:" |
|||
Debug Nth_root(125,5642) |
|||
Debug "And better:" |
|||
Debug Nth_root(125,5642,0.00001)</lang> |
|||
'''Outputs |
|||
125'th root of 5642 is |
|||
1.0715475919447675 |
|||
First estimate is: |
|||
1.0715596021916822 |
|||
And better: |
|||
1.0715475919447714 |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang="python">from decimal import Decimal, getcontext |
||
def nthroot (n, A, precision): |
def nthroot (n, A, precision): |
||
Line 2,669: | Line 3,140: | ||
x_0, x_1 = x_1, (1 / n)*((n - 1)*x_0 + (A / (x_0 ** (n - 1)))) |
x_0, x_1 = x_1, (1 / n)*((n - 1)*x_0 + (A / (x_0 ** (n - 1)))) |
||
if x_0 == x_1: |
if x_0 == x_1: |
||
return x_1</ |
return x_1</syntaxhighlight> |
||
< |
<syntaxhighlight lang="python">print nthroot(5, 34, 10) |
||
print nthroot(10,42, 20) |
print nthroot(10,42, 20) |
||
print nthroot(2, 5, 400)</ |
print nthroot(2, 5, 400)</syntaxhighlight> |
||
Or, in terms of a general '''until''' function: |
Or, in terms of a general '''until''' function: |
||
{{Works with|Python|3.7}} |
{{Works with|Python|3.7}} |
||
< |
<syntaxhighlight lang="python">'''Nth Root''' |
||
from decimal import Decimal, getcontext |
from decimal import Decimal, getcontext |
||
Line 2,787: | Line 3,258: | ||
if __name__ == '__main__': |
if __name__ == '__main__': |
||
main()</ |
main()</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>Nth roots at various precisions: |
<pre>Nth roots at various precisions: |
||
Line 2,796: | Line 3,267: | ||
=={{header|R}}== |
=={{header|R}}== |
||
< |
<syntaxhighlight lang="r">nthroot <- function(A, n, tol=sqrt(.Machine$double.eps)) |
||
{ |
{ |
||
ifelse(A < 1, x0 <- A * n, x0 <- A / n) |
ifelse(A < 1, x0 <- A * n, x0 <- A / n) |
||
Line 2,807: | Line 3,278: | ||
} |
} |
||
nthroot(7131.5^10, 10) # 7131.5 |
nthroot(7131.5^10, 10) # 7131.5 |
||
nthroot(7, 0.5) # 49</ |
nthroot(7, 0.5) # 49</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket">#lang racket |
||
(define (nth-root number root (tolerance 0.001)) |
(define (nth-root number root (tolerance 0.001)) |
||
Line 2,824: | Line 3,295: | ||
next-guess |
next-guess |
||
(loop next-guess))) |
(loop next-guess))) |
||
(loop 1.0))</ |
(loop 1.0))</syntaxhighlight> |
||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
(formerly Perl 6) |
(formerly Perl 6) |
||
<lang |
<syntaxhighlight lang="raku" line>sub infix:<√>($n, $A) { |
||
.tail given $A / $n, { (($n-1) * $_+ $A / ($_** ($n-1))) / $n } ... * ≅ *; |
|||
{ |
|||
my $x0 = $A / $n; |
|||
loop { |
|||
my $x1 = (($n-1) * $x0 + $A / ($x0 ** ($n-1))) / $n; |
|||
return $x1 if abs($x1-$x0) < abs($x0 * $p); |
|||
$x0 = $x1; |
|||
} |
|||
} |
} |
||
use Test; |
|||
say nth-root(3,8);</lang> |
|||
plan 9; |
|||
is-approx ($_√pi)**$_, pi for 2 .. 10;</syntaxhighlight> |
|||
=={{header|RATFOR}}== |
=={{header|RATFOR}}== |
||
<syntaxhighlight lang="ratfor"> |
|||
<lang RATFOR> |
|||
program nth |
program nth |
||
# |
# |
||
Line 2,878: | Line 3,345: | ||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
<pre> |
<pre> |
||
Line 2,906: | Line 3,373: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program calculates the Nth root of X, with DIGS (decimal digits) accuracy. */ |
||
parse arg x root digs . /*obtain optional arguments from the CL*/ |
parse arg x root digs . /*obtain optional arguments from the CL*/ |
||
if x=='' | x=="," then x= 2 /*Not specified? Then use the default.*/ |
if x=='' | x=="," then x= 2 /*Not specified? Then use the default.*/ |
||
Line 2,943: | Line 3,410: | ||
if \complex then g=g*sign(Ox) /*adjust the sign (maybe). */ |
if \complex then g=g*sign(Ox) /*adjust the sign (maybe). */ |
||
numeric digits oDigs /*reinstate the original digits. */ |
numeric digits oDigs /*reinstate the original digits. */ |
||
return (g/1) || left('j', complex) /*normalize # to digs, append j ?*/</ |
return (g/1) || left('j', complex) /*normalize # to digs, append j ?*/</syntaxhighlight> |
||
'''output''' when using the default inputs: |
'''output''' when using the default inputs: |
||
<pre> |
<pre> |
||
Line 2,988: | Line 3,455: | ||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
< |
<syntaxhighlight lang="ring"> |
||
decimals(12) |
decimals(12) |
||
see "cube root of 5 is : " + root(3, 5, 0) + nl |
see "cube root of 5 is : " + root(3, 5, 0) + nl |
||
Line 3,001: | Line 3,468: | ||
end |
end |
||
return x |
return x |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre> |
<pre> |
||
cube root of 5 is : 1.709975946677 |
cube root of 5 is : 1.709975946677 |
||
</pre> |
|||
=={{header|RPL}}== |
|||
{{works with|Halcyon Calc|4.2.7}} |
|||
{| class="wikitable" |
|||
! RPL code |
|||
! Comment |
|||
|- |
|||
| |
|||
≪ → a n epsilon |
|||
≪ a n / DUP |
|||
'''DO''' |
|||
SWAP DROP |
|||
a n / OVER INV n 1 - ^ * OVER n 1 - * n / + |
|||
'''UNTIL''' DUP2 - ABS epsilon < '''END''' |
|||
SWAP DROP |
|||
≫ ≫ 'NROOT' STO |
|||
| |
|||
''( a n error -- a^(1/n) ) '' |
|||
Start with x0 = x1 = a/n both in stack |
|||
Loop: |
|||
Forget x(k-1) |
|||
Calculate x(k+1) |
|||
Exit loop when x(k+1) close to xk |
|||
Forget xk |
|||
|} |
|||
{{in}} |
|||
<pre> |
|||
5 3 0.000000001 NROOT |
|||
</pre> |
|||
{{out}} |
|||
<pre> |
|||
1: 1.70997594668 |
|||
</pre> |
</pre> |
||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
< |
<syntaxhighlight lang="ruby">def nthroot(n, a, precision = 1e-5) |
||
x = Float(a) |
x = Float(a) |
||
begin |
begin |
||
Line 3,017: | Line 3,518: | ||
end |
end |
||
p nthroot(5,34) # => 2.02439745849989</ |
p nthroot(5,34) # => 2.02439745849989</syntaxhighlight> |
||
=={{header|Run BASIC}}== |
|||
<lang runbasic>print "Root 125th Root of 5643 Precision .001 ";using( "#.###############", NthRoot( 125, 5642, 0.001 )) |
|||
print "125th Root of 5643 Precision .001 ";using( "#.###############", NthRoot( 125, 5642, 0.001 )) |
|||
print "125th Root of 5643 Precision .00001 ";using( "#.###############", NthRoot( 125, 5642, 0.00001)) |
|||
print " 3rd Root of 27 Precision .00001 ";using( "#.###############", NthRoot( 3, 27, 0.00001)) |
|||
print " 2nd Root of 2 Precision .00001 ";using( "#.###############", NthRoot( 2, 2, 0.00001)) |
|||
print " 10th Root of 1024 Precision .00001 ";using( "#.###############", NthRoot( 10, 1024, 0.00001)) |
|||
wait |
|||
function NthRoot( root, A, precision) |
|||
x0 = A |
|||
x1 = A /root |
|||
while abs( x1 -x0) >precision |
|||
x0 = x1 |
|||
x1 = x1 / 1.0 ' force float |
|||
x1 = (( root -1.0) *x1 +A /x1^( root -1.0)) /root |
|||
wend |
|||
NthRoot =x1 |
|||
end function |
|||
end</lang> |
|||
<pre>125th Root of 5643 Precision .001 1.071559602456735 |
|||
125th Root of 5643 Precision .00001 1.071547591944771 |
|||
3rd Root of 27 Precision .00001 3.000000000000001 |
|||
2nd Root of 2 Precision .00001 1.414213562374690 |
|||
10th Root of 1024 Precision .00001 2.000000000000000</pre> |
|||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
{{trans|Raku}} |
{{trans|Raku}} |
||
< |
<syntaxhighlight lang="rust">// 20210212 Rust programming solution |
||
fn nthRoot(n: f64, A: f64) -> f64 { |
fn nthRoot(n: f64, A: f64) -> f64 { |
||
Line 3,065: | Line 3,538: | ||
fn main() { |
fn main() { |
||
println!("{}", nthRoot(3. , 8. )); |
println!("{}", nthRoot(3. , 8. )); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Sather}}== |
=={{header|Sather}}== |
||
{{trans|Octave}} |
{{trans|Octave}} |
||
< |
<syntaxhighlight lang="sather">class MATH is |
||
nthroot(n:INT, a:FLT):FLT |
nthroot(n:INT, a:FLT):FLT |
||
pre n > 0 |
pre n > 0 |
||
Line 3,084: | Line 3,557: | ||
end; |
end; |
||
end;</ |
end;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="sather">class MAIN is |
||
main is |
main is |
||
a:FLT := 2.5 ^ 10.0; |
a:FLT := 2.5 ^ 10.0; |
||
#OUT + MATH::nthroot(10, a) + "\n"; |
#OUT + MATH::nthroot(10, a) + "\n"; |
||
end; |
end; |
||
end;</ |
end;</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
Using tail recursion: |
Using tail recursion: |
||
< |
<syntaxhighlight lang="scala">def nroot(n: Int, a: Double): Double = { |
||
@tailrec |
@tailrec |
||
def rec(x0: Double) : Double = { |
def rec(x0: Double) : Double = { |
||
Line 3,103: | Line 3,576: | ||
rec(a) |
rec(a) |
||
}</ |
}</syntaxhighlight> |
||
Alternatively, you can implement the iteration with an iterator like so: |
Alternatively, you can implement the iteration with an iterator like so: |
||
< |
<syntaxhighlight lang="scala">def fallPrefix(itr: Iterator[Double]): Iterator[Double] = itr.sliding(2).dropWhile(p => p(0) > p(1)).map(_.head) |
||
def nrootLazy(n: Int)(a: Double): Double = fallPrefix(Iterator.iterate(a){r => (((n - 1)*r) + (a/math.pow(r, n - 1)))/n}).next</ |
def nrootLazy(n: Int)(a: Double): Double = fallPrefix(Iterator.iterate(a){r => (((n - 1)*r) + (a/math.pow(r, n - 1)))/n}).next</syntaxhighlight> |
||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
< |
<syntaxhighlight lang="scheme">(define (root number degree tolerance) |
||
(define (good-enough? next guess) |
(define (good-enough? next guess) |
||
(< (abs (- next guess)) tolerance)) |
(< (abs (- next guess)) tolerance)) |
||
Line 3,127: | Line 3,600: | ||
(newline) |
(newline) |
||
(display (root (expt 2 10) 10 0.001)) |
(display (root (expt 2 10) 10 0.001)) |
||
(newline)</ |
(newline)</syntaxhighlight> |
||
Output: |
Output: |
||
2.04732932236839 |
2.04732932236839 |
||
Line 3,138: | Line 3,611: | ||
An alternate function which uses Newton's method is: |
An alternate function which uses Newton's method is: |
||
< |
<syntaxhighlight lang="seed7">const func float: nthRoot (in integer: n, in float: a) is func |
||
result |
result |
||
var float: x1 is 0.0; |
var float: x1 is 0.0; |
||
Line 3,150: | Line 3,623: | ||
x1 := (flt(pred(n)) * x0 + a / x0 ** pred(n)) / flt(n); |
x1 := (flt(pred(n)) * x0 + a / x0 ** pred(n)) / flt(n); |
||
end while; |
end while; |
||
end func;</ |
end func;</syntaxhighlight> |
||
Original source: [http://seed7.sourceforge.net/algorith/math.htm#nthRoot] |
Original source: [http://seed7.sourceforge.net/algorith/math.htm#nthRoot] |
||
Line 3,156: | Line 3,629: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Ruby}} |
{{trans|Ruby}} |
||
< |
<syntaxhighlight lang="ruby">func nthroot(n, a, precision=1e-5) { |
||
var x = 1.float |
var x = 1.float |
||
var prev = 0.float |
var prev = 0.float |
||
Line 3,166: | Line 3,639: | ||
} |
} |
||
say nthroot(5, 34) # => 2.024397458501034082599817835297912829678314204</ |
say nthroot(5, 34) # => 2.024397458501034082599817835297912829678314204</syntaxhighlight> |
||
A minor optimization would be to calculate the successive ''int(n-1)'' square roots of a number, then raise the result to the power of ''2**(int(n-1) / n)''. |
A minor optimization would be to calculate the successive ''int(n-1)'' square roots of a number, then raise the result to the power of ''2**(int(n-1) / n)''. |
||
< |
<syntaxhighlight lang="ruby">func nthroot_fast(n, a, precision=1e-5) { |
||
{ a = nthroot(2, a, precision) } * int(n-1) |
{ a = nthroot(2, a, precision) } * int(n-1) |
||
a ** (2**int(n-1) / n) |
a ** (2**int(n-1) / n) |
||
} |
} |
||
say nthroot_fast(5, 34, 1e-64) # => 2.02439745849988504251081724554193741911462170107</ |
say nthroot_fast(5, 34, 1e-64) # => 2.02439745849988504251081724554193741911462170107</syntaxhighlight> |
||
=={{header|Smalltalk}}== |
=={{header|Smalltalk}}== |
||
Line 3,181: | Line 3,654: | ||
{{trans|Tcl}} |
{{trans|Tcl}} |
||
< |
<syntaxhighlight lang="smalltalk">Number extend [ |
||
nthRoot: n [ |
nthRoot: n [ |
||
|x0 m x1| |
|x0 m x1| |
||
Line 3,193: | Line 3,666: | ||
] |
] |
||
] |
] |
||
].</ |
].</syntaxhighlight> |
||
< |
<syntaxhighlight lang="smalltalk">(34 nthRoot: 5) displayNl. |
||
((7131.5 raisedTo: 10) nthRoot: 10) displayNl. |
((7131.5 raisedTo: 10) nthRoot: 10) displayNl. |
||
(7 nthRoot: 0.5) displayNl.</ |
(7 nthRoot: 0.5) displayNl.</syntaxhighlight> |
||
=={{header|SPL}}== |
=={{header|SPL}}== |
||
< |
<syntaxhighlight lang="spl">nthr(n,r) <= n^(1/r) |
||
nthroot(n,r)= |
nthroot(n,r)= |
||
Line 3,213: | Line 3,686: | ||
#.output(nthr(2,2)) |
#.output(nthr(2,2)) |
||
#.output(nthroot(2,2))</ |
#.output(nthroot(2,2))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,222: | Line 3,695: | ||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang="swift">extension FloatingPoint where Self: ExpressibleByFloatLiteral { |
||
@inlinable |
@inlinable |
||
public func power(_ e: Int) -> Self { |
public func power(_ e: Int) -> Self { |
||
Line 3,257: | Line 3,730: | ||
print(81.root(n: 4)) |
print(81.root(n: 4)) |
||
print(13.root(n: 5))</ |
print(13.root(n: 5))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,266: | Line 3,739: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
The easiest way is to just use the <code>pow</code> function (or exponentiation operator) like this: |
The easiest way is to just use the <code>pow</code> function (or exponentiation operator) like this: |
||
< |
<syntaxhighlight lang="tcl">proc nthroot {n A} { |
||
expr {pow($A, 1.0/$n)} |
expr {pow($A, 1.0/$n)} |
||
}</ |
}</syntaxhighlight> |
||
However that's hardly tackling the problem itself. So here's how to do it using Newton-Raphson and a self-tuning termination test.<br> |
However that's hardly tackling the problem itself. So here's how to do it using Newton-Raphson and a self-tuning termination test.<br> |
||
{{works with|Tcl|8.5}} |
{{works with|Tcl|8.5}} |
||
< |
<syntaxhighlight lang="tcl">proc nthroot {n A} { |
||
set x0 [expr {$A / double($n)}] |
set x0 [expr {$A / double($n)}] |
||
set m [expr {$n - 1.0}] |
set m [expr {$n - 1.0}] |
||
Line 3,281: | Line 3,754: | ||
set x0 $x1 |
set x0 $x1 |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Demo: |
Demo: |
||
< |
<syntaxhighlight lang="tcl">puts [nthroot 2 2] |
||
puts [nthroot 5 34] |
puts [nthroot 5 34] |
||
puts [nthroot 5 [expr {34**5}]] |
puts [nthroot 5 [expr {34**5}]] |
||
puts [nthroot 10 [expr 7131.5**10]] |
puts [nthroot 10 [expr 7131.5**10]] |
||
puts [nthroot 0.5 7]; # Squaring!</ |
puts [nthroot 0.5 7]; # Squaring!</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>1.414213562373095 |
<pre>1.414213562373095 |
||
Line 3,300: | Line 3,773: | ||
Error is on the order of machine precision because the stopping |
Error is on the order of machine precision because the stopping |
||
criterion is either a fixed point or a repeating cycle. |
criterion is either a fixed point or a repeating cycle. |
||
< |
<syntaxhighlight lang="ursala">#import nat |
||
#import flo |
#import flo |
||
Line 3,307: | Line 3,780: | ||
-+ |
-+ |
||
("n","n-1"). "A". ("x". div\"n" plus/times("n-1","x") div("A",pow("x","n-1")))^== 1., |
("n","n-1"). "A". ("x". div\"n" plus/times("n-1","x") div("A",pow("x","n-1")))^== 1., |
||
float^~/~& predecessor+-</ |
float^~/~& predecessor+-</syntaxhighlight> |
||
This implementation is unnecessary in practice due to the availability of the library |
This implementation is unnecessary in practice due to the availability of the library |
||
function pow, which performs exponentiation and allows fractional exponents. |
function pow, which performs exponentiation and allows fractional exponents. |
||
Here is a test program. |
Here is a test program. |
||
< |
<syntaxhighlight lang="ursala">#cast %eL |
||
examples = |
examples = |
||
Line 3,319: | Line 3,792: | ||
nthroot5 34., |
nthroot5 34., |
||
nthroot5 pow(34.,5.), |
nthroot5 pow(34.,5.), |
||
nthroot10 pow(7131.5,10.)></ |
nthroot10 pow(7131.5,10.)></syntaxhighlight> |
||
output: |
output: |
||
<pre> |
<pre> |
||
Line 3,329: | Line 3,802: | ||
</pre> |
</pre> |
||
=={{header| |
=={{header|V (Vlang)}}== |
||
<syntaxhighlight lang="Vlang"> |
|||
{{trans|Phix}} |
|||
import math |
|||
The internal power operator "^" is used in stead of an auxiliary pow_ function and the accuracy has been reduced. |
|||
<lang vb>Private Function nth_root(y As Double, n As Double) |
|||
fn main() { |
|||
Dim eps As Double: eps = 0.00000000000001 '-- relative accuracy |
|||
println("cube root of 5 is: ${math.cbrt(5)}") |
|||
Dim x As Variant: x = 1 |
|||
} |
|||
Do While True |
|||
</syntaxhighlight> |
|||
d = (y / x ^ (n - 1) - x) / n |
|||
x = x + d |
|||
{{out}} |
|||
e = eps * x '-- absolute accuracy |
|||
<pre> |
|||
If d > -e And d < e Then |
|||
cube root of 5 is: 1.709975946676697 |
|||
Exit Do |
|||
End If |
|||
Loop |
|||
Debug.Print y; n; x; y ^ (1 / n) |
|||
End Function |
|||
Public Sub main() |
|||
nth_root 1024, 10 |
|||
nth_root 27, 3 |
|||
nth_root 2, 2 |
|||
nth_root 5642, 125 |
|||
nth_root 7, 0.5 |
|||
nth_root 4913, 3 |
|||
nth_root 8, 3 |
|||
nth_root 16, 2 |
|||
nth_root 16, 4 |
|||
nth_root 125, 3 |
|||
nth_root 1000000000, 3 |
|||
nth_root 1000000000, 9 |
|||
End Sub</lang>{{out}} |
|||
<pre> 1024 10 2 2 |
|||
27 3 3 3 |
|||
2 2 1,41421356237309 1,4142135623731 |
|||
5642 125 1,07154759194477 1,07154759194477 |
|||
7 0,5 49 49 |
|||
4913 3 17 17 |
|||
8 3 2 2 |
|||
16 2 4 4 |
|||
16 4 2 2 |
|||
125 3 5 5 |
|||
1000000000 3 1000 1000 |
|||
1000000000 9 10 10 |
|||
</pre> |
</pre> |
||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|E}} |
{{trans|E}} |
||
< |
<syntaxhighlight lang="wren">var nthRoot = Fn.new { |x, n| |
||
if (n < 2) Fiber.abort("n must be more than 1") |
if (n < 2) Fiber.abort("n must be more than 1") |
||
if (x <= 0) Fiber.abort("x must be positive") |
if (x <= 0) Fiber.abort("x must be positive") |
||
Line 3,392: | Line 3,835: | ||
for (trio in trios) { |
for (trio in trios) { |
||
System.print("%(trio[0]) ^ 1/%(trio[1])%(" "*trio[2]) = %(nthRoot.call(trio[0], trio[1]))") |
System.print("%(trio[0]) ^ 1/%(trio[1])%(" "*trio[2]) = %(nthRoot.call(trio[0], trio[1]))") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,402: | Line 3,845: | ||
=={{header|XBS}}== |
=={{header|XBS}}== |
||
< |
<syntaxhighlight lang="xbs">func nthRoot(x,a){ |
||
send x^(1/a); |
send x^(1/a); |
||
}{a=2}; |
}{a=2}; |
||
log(nthRoot(8,3));</ |
log(nthRoot(8,3));</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,412: | Line 3,855: | ||
=={{header|XPL0}}== |
=={{header|XPL0}}== |
||
< |
<syntaxhighlight lang="xpl0">include c:\cxpl\stdlib; |
||
func real NRoot(A, N); \Return the Nth root of A |
func real NRoot(A, N); \Return the Nth root of A |
||
Line 3,432: | Line 3,875: | ||
RlOut(0, NRoot(27., 3.)); CrLf(0); |
RlOut(0, NRoot(27., 3.)); CrLf(0); |
||
RlOut(0, NRoot(1024.,10.)); CrLf(0); |
RlOut(0, NRoot(1024.,10.)); CrLf(0); |
||
]</ |
]</syntaxhighlight> |
||
Output: |
Output: |
||
Line 3,441: | Line 3,884: | ||
2.000000000000000 |
2.000000000000000 |
||
</pre> |
</pre> |
||
=={{header|Yabasic}}== |
|||
{{trans|AWK}} |
|||
<lang Yabasic>data 10, 1024, 3, 27, 2, 2, 125, 5642, 4, 16, 0, 0 |
|||
do |
|||
read e, b |
|||
if e = 0 break |
|||
print "The ", e, "th root of ", b, " is ", b^(1/e), " (", nthroot(b, e), ")" |
|||
loop |
|||
sub nthroot(y, n) |
|||
local eps, x, d, e |
|||
eps = 1e-15 // relative accuracy |
|||
x = 1 |
|||
repeat |
|||
d = ( y / ( x^(n-1) ) - x ) / n |
|||
x = x + d |
|||
e = eps * x // absolute accuracy |
|||
until(not(d < -e or d > e )) |
|||
return x |
|||
end sub</lang> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{trans|Ruby}} |
{{trans|Ruby}} |
||
< |
<syntaxhighlight lang="zkl">fcn nthroot(nth,a,precision=1.0e-5){ |
||
x:=prev:=a=a.toFloat(); n1:=nth-1; |
x:=prev:=a=a.toFloat(); n1:=nth-1; |
||
do{ |
do{ |
||
Line 3,480: | Line 3,897: | ||
} |
} |
||
nthroot(5,34) : "%.20f".fmt(_).println() # => 2.02439745849988828041</ |
nthroot(5,34) : "%.20f".fmt(_).println() # => 2.02439745849988828041</syntaxhighlight> |
||
Latest revision as of 13:39, 14 April 2024
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Implement the algorithm to compute the principal nth root of a positive real number A, as explained at the Wikipedia page.
11l
F nthroot(a, n)
V result = a
V x = a / n
L abs(result - x) > 10e-15
x = result
result = (1.0 / n) * (((n - 1) * x) + (a / pow(x, n - 1)))
R result
print(nthroot(34.0, 5))
print(nthroot(42.0, 10))
print(nthroot(5.0, 2))
- Output:
2.0244 1.4532 2.23607
360 Assembly
An example of converting integer floating-point using unnormalized short format. The 'include' file FORMAT, to format a floating point number, can be found in: Include files 360 Assembly.
* Nth root - x**(1/n) - 29/07/2018
NTHROOT CSECT
USING NTHROOT,R13 base register
B 72(R15) skip savearea
DC 17F'0' savearea
SAVE (14,12) save previous context
ST R13,4(R15) link backward
ST R15,8(R13) link forward
LR R13,R15 set addressability
BAL R14,ROOTN call rootn(x,n)
LE F0,XN xn=rootn(x,n)
LA R0,6 decimals=6
BAL R14,FORMATF edit xn
MVC PG(13),0(R1) output xn
XPRNT PG,L'PG print buffer
L R13,4(0,R13) restore previous savearea pointer
RETURN (14,12),RC=0 restore registers from calling sav
ROOTN MVC ZN,=E'0' zn=0 ----------------------------
MVC ZN,N n
MVI ZN,X'46' zn=unnormalize(n)
LE F0,ZN zn
AE F0,=E'0' normalized
STE F0,ZN zn=normalize(n)
LE F6,=E'0' xm=0
LE F0,X x
DE F0,ZN /zn
STE F0,XN xn=x/zn
WHILEA LE F0,XN xn
SER F0,F6 xn-xm
LPER F0,F0 abs((xn-xm)
DE F0,XN /xn
CE F0,EPSILON while abs((xn-xm)/xn)>epsilon
BNH EWHILEA ~
LE F6,XN xm=xn
LE F0,ZN zn
SE F0,=E'1' zn-1
MER F0,F6 f0=(zn-1)*xm
L R2,N n
BCTR R2,0 n-1
LE F2,=E'1' xm
POW MER F2,F6 *xm
BCT R2,POW f2=xm**(n-1)
LE F4,X x
DER F4,F2 x/xm**(n-1)
AER F0,F4 (zn-1)*xm+x/xm**(n-1)
DE F0,ZN /zn
STE F0,XN xn=((zn-1)*xm+x/xm**(n-1))/zn
B WHILEA endwhile
EWHILEA LE F0,XN xn
BR R14 return ---------------------------
COPY FORMATF format a float
X DC E'2' x <== input
N DC F'2' n <== input
EPSILON DC E'1E-6' imprecision
XN DS E xn :: output
ZN DS E zn=float(n)
PG DC CL80' ' buffer
REGEQU
END NTHROOT
- Output:
1.414213
AArch64 Assembly
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program nroot64.s */
/* link with gcc. Use C function for display float */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
/*******************************************/
/* Initialized data */
/*******************************************/
.data
szFormat1: .asciz "Root= %+09.15f\n"
.align 4
qNumberA: .quad 1024
/*******************************************/
/* UnInitialized data */
/*******************************************/
.bss
.align 4
/*******************************************/
/* code section */
/*******************************************/
.text
.global main
main: // entry of program
/* root 10ieme de 1024 */
ldr x0,qAdriNumberA // number address
ldr d0,[x0] // load number in registre d0
scvtf d0,d0 // conversion in float
mov x0,#10 // N
bl nthRoot
ldr x0,qAdrszFormat1 // format
bl printf // call C function !!!
// Attention register dn lost !!!
/* square root of 2 */
fmov d0,2 // conversion 2 in float register d0
mov x0,#2 // N
bl nthRoot
ldr x0,qAdrszFormat1 // format
// d0 contains résult
bl printf // call C function !!!
100: // standard end of the program
mov x0, #0 // return code
mov x8, #EXIT // request to exit program
svc 0 // perform the system call
qAdrszFormat1: .quad szFormat1
qAdriNumberA: .quad qNumberA
/******************************************************************/
/* compute nth root */
/******************************************************************/
/* x0 contains N */
/* d0 contains the value */
/* x0 return result */
nthRoot:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp d1,d2,[sp,-16]! // save float registers
stp d3,d4,[sp,-16]! // save float registers
stp d5,d6,[sp,-16]! // save float registers
stp d7,d8,[sp,-16]! // save float registers
fmov d6,x0 //
scvtf d6,d6 // N conversion in float double précision (64 bits)
sub x1,x0,#1 // N - 1
fmov d8,x1 //
scvtf d4,d8 //conversion in float double précision
fmov d2,d0 // a = A
fdiv d3,d0,d6 // b = A/n
adr x2,dfPrec // load précision
ldr d8,[x2]
1: // begin loop
fmov d2,d3 // a <- b
fmul d5,d3,d4 // (N-1)*b
fmov d1,1 // constante 1 -> float
mov x2,0 // loop indice
2: // compute pow (n-1)
fmul d1,d1,d3 //
add x2,x2,1
cmp x2,x1 // n -1 ?
blt 2b // no -> loop
fdiv d7,d0,d1 // A / b pow (n-1)
fadd d7,d7,d5 // + (N-1)*b
fdiv d3,d7,d6 // / N -> new b
fsub d1,d3,d2 // compute gap
fabs d1,d1 // absolute value
fcmp d1,d8 // compare float maj FPSCR
bgt 1b // if gap > précision -> loop
fmov d0,d3 // end return result in d0
100:
ldp d7,d8,[sp],16 // restaur 2 float registers
ldp d5,d6,[sp],16 // restaur 2 float registers
ldp d3,d4,[sp],16 // restaur 2 float registers
ldp d1,d2,[sp],16 // restaur 2 float registers
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
dfPrec: .double 0f1E-10 // précision
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
- Output:
Root= +2.000000000000000 Root= +1.414213562373095
Action!
INCLUDE "H6:REALMATH.ACT"
PROC NthRoot(REAL POINTER a,n REAL POINTER res)
REAL n1,eps,one,tmp1,tmp2,tmp3
ValR("0.0001",eps)
IntToReal(1,one)
RealSub(n,one,n1)
Sqrt(a,res) ;res=sqrt(a)
DO
Power(res,n,tmp1) ;tmp=res^n
RealSub(a,tmp1,tmp2) ;tmp2=a-res^n
RealAbs(tmp2,tmp1) ;tmp1=abs(a-res^n)
IF RealGreaterOrEqual(eps,tmp1) THEN
RETURN
FI
Power(res,n1,tmp1) ;tmp1=res^(n-1)
RealDiv(a,tmp1,tmp2) ;tmp2=a/(res^(n-1))
RealMult(n1,res,tmp1) ;tmp1=(n-1)*res
RealAdd(tmp1,tmp2,tmp3) ;tmp3=((n-1)*res + a/(res^(n-1)))
RealDiv(tmp3,n,res) ;res=((n-1)*res + a/(res^(n-1)))/n
OD
RETURN
PROC Test(CHAR ARRAY sa,sn)
REAL a,n,res
ValR(sa,a)
ValR(sn,n)
PrintR(n) Print(" root of ")
PrintR(a) Print(" is ")
NthRoot(a,n,res)
PrintRE(res)
RETURN
PROC Main()
Put(125) PutE() ;clear screen
MathInit()
Test("2","2")
Test("81","4")
Test("1024","10")
Test("7","0.5")
Test("12.34","56.78")
RETURN
- Output:
Screenshot from Atari 8-bit computer
2 root of 2 is 1.41421355 4 root of 81 is 3.00000047 10 root of 1024 is 2.00000001 .5 root of 7 is 48.99975418 56.78 root of 12.34 is 1.04524972
Ada
The implementation is generic and supposed to work with any floating-point type. There is no result accuracy argument of Nth_Root, because the iteration is supposed to be monotonically descending to the root when starts at A. Thus it should converge when this condition gets violated, i.e. when xk+1≥xk.
with Ada.Text_IO; use Ada.Text_IO;
procedure Test_Nth_Root is
generic
type Real is digits <>;
function Nth_Root (Value : Real; N : Positive) return Real;
function Nth_Root (Value : Real; N : Positive) return Real is
type Index is mod 2;
X : array (Index) of Real := (Value, Value);
K : Index := 0;
begin
loop
X (K + 1) := ( (Real (N) - 1.0) * X (K) + Value / X (K) ** (N-1) ) / Real (N);
exit when X (K + 1) >= X (K);
K := K + 1;
end loop;
return X (K + 1);
end Nth_Root;
function Long_Nth_Root is new Nth_Root (Long_Float);
begin
Put_Line ("1024.0 10th =" & Long_Float'Image (Long_Nth_Root (1024.0, 10)));
Put_Line (" 27.0 3rd =" & Long_Float'Image (Long_Nth_Root (27.0, 3)));
Put_Line (" 2.0 2nd =" & Long_Float'Image (Long_Nth_Root (2.0, 2)));
Put_Line ("5642.0 125th =" & Long_Float'Image (Long_Nth_Root (5642.0, 125)));
end Test_Nth_Root;
Sample output:
1024.0 10th = 2.00000000000000E+00 27.0 3rd = 3.00000000000000E+00 2.0 2nd = 1.41421356237310E+00 5642.0 125th = 1.07154759194477E+00
ALGOL 68
REAL default p = 0.001;
PROC nth root = (INT n, LONG REAL a, p)LONG REAL:
(
[2]LONG REAL x := (a, a/n);
WHILE ABS(x[2] - x[1]) > p DO
x := (x[2], ((n-1)*x[2] + a/x[2]**(n-1))/n )
OD;
x[2]
);
PRIO ROOT = 8;
OP ROOT = (INT n, LONG REAL a)LONG REAL: nth root(n, a, default p);
OP ROOT = (INT n, INT a)LONG REAL: nth root(n, a, default p);
main:
(
printf(($2(" "gl)$,
nth root(10, LONG 7131.5 ** 10, default p),
nth root(5, 34, default p)));
printf(($2(" "gl)$,
10 ROOT ( LONG 7131.5 ** 10 ),
5 ROOT 34))
)
Output:
+7.131500000000000000001144390e +3 +2.024397462171090138953733623e +0 +7.131500000000000000001144390e +3 +2.024397462171090138953733623e +0
ALGOL W
begin
% nth root algorithm %
% returns the nth root of A, A must be > 0 %
% the required precision should be specified in precision %
long real procedure nthRoot( long real value A
; integer value n
; long real value precision
) ;
begin
long real xk, xd;
integer n1;
n1 := n - 1;
xk := A / n;
while begin
xd := ( ( A / ( xk ** n1 ) ) - xk ) / n;
xk := xk + xd;
abs( xd ) > precision
end do begin end;
xk
end nthRoot ;
% test cases %
r_format := "A"; r_w := 15; r_d := 6; % set output format %
write( nthRoot( 7131.5 ** 10, 10, 1'-5 ) );
write( nthRoot( 64, 6, 1'-5 ) );
end.
- Output:
7131.500000 2.000000
ARM Assembly
/* ARM assembly Raspberry PI */
/* program nroot.s */
/* compile with option -mfpu=vfpv3 -mfloat-abi=hard */
/* link with gcc. Use C function for display float */
/* Constantes */
.equ EXIT, 1 @ Linux syscall
/* Initialized data */
.data
szFormat1: .asciz " %+09.15f\n"
.align 4
iNumberA: .int 1024
/* UnInitialized data */
.bss
.align 4
/* code section */
.text
.global main
main: @ entry of program
push {fp,lr} @ saves registers
/* root 10ieme de 1024 */
ldr r0,iAdriNumberA @ number address
ldr r0,[r0]
vmov s0,r0 @
vcvt.f64.s32 d0, s0 @conversion in float single précision (32 bits)
mov r0,#10 @ N
bl nthRoot
ldr r0,iAdrszFormat1 @ format
vmov r2,r3,d0
bl printf @ call C function !!!
@ Attention register dn lost !!!
/* square root of 2 */
vmov.f64 d1,#2.0 @ conversion 2 in float register d1
mov r0,#2 @ N
bl nthRoot
ldr r0,iAdrszFormat1 @ format
vmov r2,r3,d0
bl printf @ call C function !!!
100: @ standard end of the program
mov r0, #0 @ return code
pop {fp,lr} @restaur registers
mov r7, #EXIT @ request to exit program
swi 0 @ perform the system call
iAdrszFormat1: .int szFormat1
iAdriNumberA: .int iNumberA
/******************************************************************/
/* compute nth root */
/******************************************************************/
/* r0 contains N */
/* d0 contains the value */
/* d0 return result */
nthRoot:
push {r1,r2,lr} @ save registers
vpush {d1-d8} @ save float registers
FMRX r1,FPSCR @ copy FPSCR into r1
BIC r1,r1,#0x00370000 @ clears STRIDE and LEN
FMXR FPSCR,r1 @ copy r1 back into FPSCR
vmov s2,r0 @
vcvt.f64.s32 d6, s2 @ N conversion in float double précision (64 bits)
sub r1,r0,#1 @ N - 1
vmov s8,r1 @
vcvt.f64.s32 d4, s8 @conversion in float double précision (64 bits)
vmov.f64 d2,d0 @ a = A
vdiv.F64 d3,d0,d6 @ b = A/n
adr r2,dfPrec @ load précision
vldr d8,[r2]
1: @ begin loop
vmov.f64 d2,d3 @ a <- b
vmul.f64 d5,d3,d4 @ (N-1)*b
vmov.f64 d1,#1.0 @ constante 1 -> float
mov r2,#0 @ loop indice
2: @ compute pow (n-1)
vmul.f64 d1,d1,d3 @
add r2,#1
cmp r2,r1 @ n -1 ?
blt 2b @ no -> loop
vdiv.f64 d7,d0,d1 @ A / b pow (n-1)
vadd.f64 d7,d7,d5 @ + (N-1)*b
vdiv.f64 d3,d7,d6 @ / N -> new b
vsub.f64 d1,d3,d2 @ compute gap
vabs.f64 d1,d1 @ absolute value
vcmp.f64 d1,d8 @ compare float maj FPSCR
fmstat @ transfert FPSCR -> APSR
@ or use VMRS APSR_nzcv, FPSCR
bgt 1b @ if gap > précision -> loop
vmov.f64 d0,d3 @ end return result in d0
100:
vpop {d1-d8} @ restaur float registers
pop {r1,r2,lr} @ restaur arm registers
bx lr
dfPrec: .double 0f1E-10 @ précision
Arturo
nthRoot: function [a,n][
N: to :floating n
result: a
x: a / N
while [0.000000000000001 < abs result-x][
x: result
result: (1//n) * add (n-1)*x a/pow x n-1
]
return result
]
print nthRoot 34.0 5
print nthRoot 42.0 10
print nthRoot 5.0 2
- Output:
2.024397458499885 1.453198460282268 2.23606797749979
AutoHotkey
p := 0.000001
MsgBox, % nthRoot( 10, 7131.5**10, p) "`n"
. nthRoot( 5, 34.0 , p) "`n"
. nthRoot( 2, 2 , p) "`n"
. nthRoot(0.5, 7 , p) "`n"
;---------------------------------------------------------------------------
nthRoot(n, A, p) { ; http://en.wikipedia.org/wiki/Nth_root_algorithm
;---------------------------------------------------------------------------
x1 := A
x2 := A / n
While Abs(x1 - x2) > p {
x1 := x2
x2 := ((n-1)*x2+A/x2**(n-1))/n
}
Return, x2
}
Message box shows:
7131.500000 2.024397 1.414214 49.000000
AutoIt
;AutoIt Version: 3.2.10.0
$A=4913
$n=3
$x=20
ConsoleWrite ($n& " root of "& $A & " is " &nth_root_it($A,$n,$x))
ConsoleWrite ($n& " root of "& $A & " is " &nth_root_rec($A,$n,$x))
;Iterative
Func nth_root_it($A,$n,$x)
$x0="0"
While StringCompare(string($x0),string($x))
ConsoleWrite ($x&@CRLF)
$x0=$x
$x=((($n-1)*$x)+($A/$x^($n-1)))/$n
WEnd
Return $x
EndFunc
;Recursive
Func nth_root_rec($A,$n,$x)
ConsoleWrite ($x&@CRLF)
If $x==((($n-1)*$x)+($A/$x^($n-1)))/$n Then
Return $x
EndIf
Return nth_root_rec($A,$n,((($n-1)*$x)+($A/$x^($n-1)))/$n)
EndFunc
output :
20 17.4275 17.0104009124137 17.0000063582823 17.0000000000024 17 3 root of 4913 is 17
AWK
#!/usr/bin/awk -f
BEGIN {
# test
print nthroot(8,3)
print nthroot(16,2)
print nthroot(16,4)
print nthroot(125,3)
print nthroot(3,3)
print nthroot(3,2)
}
function nthroot(y,n) {
eps = 1e-15; # relative accuracy
x = 1;
do {
d = ( y / ( x^(n-1) ) - x ) / n ;
x += d;
e = eps*x; # absolute accuracy
} while ( d < -e || d > e )
return x
}
Sample output:
2 4 2 5 1.44225 1.73205
BASIC
This function is fairly generic MS BASIC. It could likely be used in most modern BASICs with little or no change.
FUNCTION RootX (tBase AS DOUBLE, tExp AS DOUBLE, diffLimit AS DOUBLE) AS DOUBLE
DIM tmp1 AS DOUBLE, tmp2 AS DOUBLE
' Initial guess:
tmp1 = tBase / tExp
DO
tmp2 = tmp1
' 1# tells compiler that "1" is a double, not an integer
tmp1 = (((tExp - 1#) * tmp2) + (tBase / (tmp2 ^ (tExp - 1#)))) / tExp
LOOP WHILE (ABS(tmp1 - tmp2) > diffLimit)
RootX = tmp1
END FUNCTION
Note that for the above to work in QBasic, the function definition needs to be changed like so:
FUNCTION RootX# (tBase AS DOUBLE, tExp AS DOUBLE, diffLimit AS DOUBLE)
The function is called like so:
PRINT "The "; e; "th root of "; b; " is "; RootX(b, e, .000001)
Sample output:
The 4th root of 16 is 2
For BASICs without the ^ operator, it would be trivial to write a function to reproduce it (as is done in the C example below).
See also the Liberty BASIC and PureBasic solutions.
Basic09
PROCEDURE nth
PARAM N : INTEGER; A, P : REAL
DIM TEMP0, TEMP1 : REAL
TEMP0 := A
TEMP1 := A/N
WHILE ( abs(TEMP0 - TEMP1) > P) DO
TEMP0 := TEMP1
TEMP1 := (( N - 1.0) * TEMP1 + A / TEMP1 ^ (N - 1.0)) / N
ENDWHILE
PRINT "Root Number Precision"
PRINT N, A, P
PRINT "The Root is: ";TEMP1
END
BASIC256
function nth_root(n, a)
precision = 0.0001
dim x(2)
x[0] = a
x[1] = a /n
while abs(x[1] - x[0]) > precision
x[0] = x[1]
x[1] = ((n -1.0) * x[1] +a / x[1]^(n -1.0)) / n
end while
return x[1]
end function
print " n 5643 ^ 1 / n nth_root ^ n"
print " --------------------------------------"
for n = 3 to 11 step 2
tmp = nth_root(n, 5643)
print " "; n; " "; tmp; chr(9); (tmp ^ n)
next n
print
for n = 25 to 125 step 25
tmp = nth_root(n, 5643)
print n; " "; tmp; chr(9); (tmp ^ n)
next n
BBC BASIC
*FLOAT 64
@% = &D0D
PRINT "Cube root of 5 is "; FNroot(3, 5, 0)
PRINT "125th root of 5643 is "; FNroot(125, 5643, 0)
END
DEF FNroot(n%, a, d)
LOCAL x0, x1 : x0 = a / n% : REM Initial guess
REPEAT
x1 = ((n% - 1)*x0 + a/x0^(n%-1)) / n%
SWAP x0, x1
UNTIL ABS (x0 - x1) <= d
= x0
Output:
Cube root of 5 is 1.709975946677 125th root of 5643 is 1.071549111198
Chipmunk Basic
10 rem Nth root
20 print "Finding the nth root of 144 to 6 decimal places"
30 print " x n root"
40 print "------------------------"
50 for i = 1 to 8
60 print using "### ";144;
70 print using "#### ";i;
80 print using "###.######";nthroot(i,144,1.000000E-07)
90 next i
100 end
1000 sub nthroot(n,x,precision)
1010 rem Returns the nth root of value x to stated precision
1020 x0 = x
1030 x1 = x/n ' - initial guess
1040 while abs(x1-x0) > precision
1050 x0 = x1
1060 x1 = ((n-1)*x1+x/x1^(n-1))/n
1070 wend
1080 nthroot = x1
1090 end sub
- Output:
Finding the nth root of 144 to 6 decimal places x n root ------------------------ 144 1 144.000000 144 2 12.000000 144 3 5.241483 144 4 3.464102 144 5 2.701920 144 6 2.289428 144 7 2.033937 144 8 1.861210
Craft Basic
precision 6
let a = int(rnd * 5999) + 2
print "calculating nth root of ", a, "..."
for n = 1 to 10
gosub nroot
print n, " : ", y
next n
end
sub nroot
let p = .00001
let x = a
let y = a / n
do
if abs(x - y) > p then
let x = y
let y = ((n - 1) * y + a / y ^ (n - 1)) / n
endif
wait
loop abs(x - y) > p
return
- Output:
calculating nth root of 634...1 : 634 2 : 25.179356 3 : 8.590724 4 : 5.017903 5 : 3.634275 6 : 2.930994 7 : 2.513613 8 : 2.240068 9 : 2.048063
10 : 1.906378
FreeBASIC
' version 14-01-2019
' compile with: fbc -s console
Function nth_root(n As Integer, number As Double) As Double
Dim As Double a1 = number / n, a2 , a3
Do
a3 = Abs(a2 - a1)
a2 = ((n -1) * a1 + number / a1 ^ (n -1)) / n
Swap a1, a2
Loop Until Abs(a2 - a1) = a3
Return a1
End Function
' ------=< MAIN >=------
Dim As UInteger n
Dim As Double tmp
Print
Print " n 5643 ^ 1 / n nth_root ^ n"
Print " ------------------------------------"
For n = 3 To 11 Step 2
tmp = nth_root(n, 5643)
Print Using " ### ###.######## ####.########"; n; tmp; tmp ^ n
Next
Print
For n = 25 To 125 Step 25
tmp = nth_root(n, 5643)
Print Using " ### ###.######## ####.########"; n; tmp; tmp ^ n
Next
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End
- Output:
n 5643 ^ 1 / n nth_root ^ n ------------------------------------ 3 17.80341642 5643.00000000 5 5.62732516 5643.00000000 7 3.43502583 5643.00000000 9 2.61116581 5643.00000000 11 2.19303907 5643.00000000 25 1.41273402 5643.00000000 50 1.18858488 5643.00000000 75 1.12207047 5643.00000000 100 1.09022240 5643.00000000 125 1.07154911 5643.00000000
FutureBasic
window 1
local fn NthRoot( root as long, a as long, precision as double ) as double
double x0, x1
x0 = a : x1 = a /root
while ( abs( x1 - x0 ) > precision )
x0 = x1
x1 = ( ( root -1.0 ) * x1 + a / x1 ^ ( root -1.0 ) ) /root
wend
end fn = x1
print " 125th Root of 5643 Precision .001",, using "#.###############"; fn NthRoot( 125, 5642, 0.001 )
print " 125th Root of 5643 Precision .001",, using "#.###############"; fn NthRoot( 125, 5642, 0.001 )
print " 125th Root of 5643 Precision .00001", using "#.###############"; fn NthRoot( 125, 5642, 0.00001 )
print " Cube Root of 27 Precision .00001", using "#.###############"; fn NthRoot( 3, 27, 0.00001 )
print "Square Root of 2 Precision .00001", using "#.###############"; fn NthRoot( 2, 2, 0.00001 )
print "Square Root of 2 Precision .00001", using "#.###############"; sqr(2) // Processor floating point calc deviation
print " 10th Root of 1024 Precision .00001", using "#.###############"; fn NthRoot( 10, 1024, 0.00001 )
print " 5th Root of 34 Precision .00001", using "#.###############"; fn NthRoot( 5, 34, 0.00001 )
HandleEvents
Output:
125th Root of 5643 Precision .001 1.071559602191682 125th Root of 5643 Precision .001 1.071559602191682 125th Root of 5643 Precision .00001 1.071547591944772 Cube Root of 27 Precision .00001 3.000000000000002 Square Root of 2 Precision .00001 1.414213562374690 Square Root of 2 Precision .00001 1.414213562373095 10th Root of 1024 Precision .00001 2.000000000000000 5th Root of 34 Precision .00001 2.024397458499885
Liberty BASIC
print "First estimate is: ", using( "#.###############", NthRoot( 125, 5642, 0.001 ));
print " ... and better is: ", using( "#.###############", NthRoot( 125, 5642, 0.00001))
print "125'th root of 5642 by LB's exponentiation operator is "; using( "#.###############", 5642^(1 /125))
print "27^(1 / 3)", using( "#.###############", NthRoot( 3, 27, 0.00001))
print "2^(1 / 2)", using( "#.###############", NthRoot( 2, 2, 0.00001))
print "1024^(1 /10)", using( "#.###############", NthRoot( 10, 1024, 0.00001))
wait
function NthRoot( n, A, p)
x( 0) =A
x( 1) =A /n
while abs( x( 1) -x( 0)) >p
x( 0) =x( 1)
x( 1) =( ( n -1.0) *x( 1) +A /x( 1)^( n -1.0)) /n
wend
NthRoot =x( 1)
end function
end
- Output:
First estimate is: 1.071559602191682 ... and better is: 1.071547591944771 125'th root of 5642 by LB's exponentiation operator is 1.071547591944767 27^(1 / 3) 3.000000000000002 2^(1 / 2) 1.414213562374690 1024^(1 /10) 2.000000000000000
PureBasic
#Def_p=0.001
Procedure.d Nth_root(n.i, A.d, p.d=#Def_p)
Protected Dim x.d(1)
x(0)=A: x(1)=A/n
While Abs(x(1)-x(0))>p
x(0)=x(1)
x(1)=((n-1.0)*x(1)+A/Pow(x(1),n-1.0))/n
Wend
ProcedureReturn x(1)
EndProcedure
;//////////////////////////////
Debug "125'th root of 5642 is"
Debug Pow(5642,1/125)
Debug "First estimate is:"
Debug Nth_root(125,5642)
Debug "And better:"
Debug Nth_root(125,5642,0.00001)
- Output:
125'th root of 5642 is 1.0715475919447675 First estimate is: 1.0715596021916822 And better: 1.0715475919447714
Run BASIC
print "Root 125th Root of 5643 Precision .001 ";using( "#.###############", NthRoot( 125, 5642, 0.001 ))
print "125th Root of 5643 Precision .001 ";using( "#.###############", NthRoot( 125, 5642, 0.001 ))
print "125th Root of 5643 Precision .00001 ";using( "#.###############", NthRoot( 125, 5642, 0.00001))
print " 3rd Root of 27 Precision .00001 ";using( "#.###############", NthRoot( 3, 27, 0.00001))
print " 2nd Root of 2 Precision .00001 ";using( "#.###############", NthRoot( 2, 2, 0.00001))
print " 10th Root of 1024 Precision .00001 ";using( "#.###############", NthRoot( 10, 1024, 0.00001))
wait
function NthRoot( root, A, precision)
x0 = A
x1 = A /root
while abs( x1 -x0) >precision
x0 = x1
x1 = x1 / 1.0 ' force float
x1 = (( root -1.0) *x1 +A /x1^( root -1.0)) /root
wend
NthRoot =x1
end function
end
125th Root of 5643 Precision .001 1.071559602456735 125th Root of 5643 Precision .00001 1.071547591944771 3rd Root of 27 Precision .00001 3.000000000000001 2nd Root of 2 Precision .00001 1.414213562374690 10th Root of 1024 Precision .00001 2.000000000000000
S-BASIC
When single precision results are sufficient for the task at hand, resort to Newton's method seems unnecessarily cumbersome, given the ready availability of S-BASIC's built-in exp and natural log functions.
rem - return nth root of x
function nthroot(x, n = real) = real
end = exp((1.0 / n) * log(x))
rem - exercise the routine by finding successive roots of 144
var i = integer
print "Finding the nth root of x"
print " x n root"
print "-----------------------"
for i = 1 to 8
print using "### #### ###.####"; 144; i; nthroot(144, i)
next i
end
But if the six or seven digits supported by S-BASIC's single-precision REAL data type is insufficient, Newton's Method is the way to go, given that the built-in exp and natural log functions are only single-precision.
rem - return the nth root of real.double value x to stated precision
function nthroot(n, x, precision = real.double) = real.double
var x0, x1 = real.double
x0 = x
x1 = x / n rem - initial guess
while abs(x1 - x0) > precision do
begin
x0 = x1
x1 = ((n-1.0) * x1 + x / x1 ^ (n-1.0)) / n
end
end = x1
rem -- exercise the routine
var i = integer
print "Finding the nth root of 144 to 6 decimal places"
print " x n root"
print "------------------------"
for i = 1 to 8
print using "### #### ###.######"; 144; i; nthroot(i, 144.0, 1E-7)
next i
end
- Output:
From the second version of the program.
Finding the nth root of 144 to 6 decimal places x n root ------------------------- 144 1 144.000000 144 2 12.000000 144 3 5.241483 144 4 3.464102 144 5 2.701920 144 6 2.289428 144 7 2.033937 144 8 1.861210
True BASIC
FUNCTION Nroot (n, a)
LET precision = .00001
LET x1 = a
LET x2 = a / n
DO WHILE ABS(x2 - x1) > precision
LET x1 = x2
LET x2 = ((n - 1) * x2 + a / x2 ^ (n - 1)) / n
LOOP
LET Nroot = x2
END FUNCTION
PRINT " n 5643 ^ 1 / n nth_root ^ n"
PRINT " ------------------------------------"
FOR n = 3 TO 11 STEP 2
LET tmp = Nroot(n, 5643)
PRINT USING "####": n;
PRINT " ";
PRINT USING "###.########": tmp;
PRINT " ";
PRINT USING "####.########": (tmp ^ n)
NEXT n
PRINT
FOR n = 25 TO 125 STEP 25
LET tmp = Nroot(n, 5643)
PRINT USING "####": n;
PRINT " ";
PRINT USING "###.########": tmp;
PRINT " ";
PRINT USING "####.########": (tmp ^ n)
NEXT n
END
Yabasic
data 10, 1024, 3, 27, 2, 2, 125, 5642, 4, 16, 0, 0
do
read e, b
if e = 0 break
print "The ", e, "th root of ", b, " is ", b^(1/e), " (", nthroot(b, e), ")"
loop
sub nthroot(y, n)
local eps, x, d, e
eps = 1e-15 // relative accuracy
x = 1
repeat
d = ( y / ( x^(n-1) ) - x ) / n
x = x + d
e = eps * x // absolute accuracy
until(not(d < -e or d > e ))
return x
end sub
VBA
The internal power operator "^" is used in stead of an auxiliary pow_ function and the accuracy has been reduced.
Private Function nth_root(y As Double, n As Double)
Dim eps As Double: eps = 0.00000000000001 '-- relative accuracy
Dim x As Variant: x = 1
Do While True
d = (y / x ^ (n - 1) - x) / n
x = x + d
e = eps * x '-- absolute accuracy
If d > -e And d < e Then
Exit Do
End If
Loop
Debug.Print y; n; x; y ^ (1 / n)
End Function
Public Sub main()
nth_root 1024, 10
nth_root 27, 3
nth_root 2, 2
nth_root 5642, 125
nth_root 7, 0.5
nth_root 4913, 3
nth_root 8, 3
nth_root 16, 2
nth_root 16, 4
nth_root 125, 3
nth_root 1000000000, 3
nth_root 1000000000, 9
End Sub
- Output:
1024 10 2 2 27 3 3 3 2 2 1,41421356237309 1,4142135623731 5642 125 1,07154759194477 1,07154759194477 7 0,5 49 49 4913 3 17 17 8 3 2 2 16 2 4 4 16 4 2 2 125 3 5 5 1000000000 3 1000 1000 1000000000 9 10 10
bc
/* Take the nth root of 'a' (a positive real number).
* 'n' must be an integer.
* Result will have 'd' digits after the decimal point.
*/
define r(a, n, d) {
auto e, o, x, y, z
if (n == 0) return(1)
if (a == 0) return(0)
o = scale
scale = d
e = 1 / 10 ^ d
if (n < 0) {
n = -n
a = 1 / a
}
x = 1
while (1) {
y = ((n - 1) * x + a / x ^ (n - 1)) / n
z = x - y
if (z < 0) z = -z
if (z < e) break
x = y
}
scale = o
return(y)
}
BQN
There are two builtin methods to solve this problem(√
and ⋆
), both give a result at the highest precision possible.
Root2
is a translation of the Run BASIC implementation, which uses Newton's approximation method. It allows an optional argument for precision, and otherwise defaults to 10¯5.
_while_
is a BQNcrate idiom used for unbounded looping here.
_while_ ← {𝔽⍟𝔾∘𝔽_𝕣_𝔾∘𝔽⍟𝔾𝕩}
Root ← √
Root1 ← ⋆⟜÷˜
Root2 ← {
n 𝕊 a‿prec:
1⊑{
p‿x:
⟨
x
((p × n - 1) + a ÷ p ⋆ n - 1) ÷ n
⟩
} _while_ {
p‿x:
prec ≤ | p - x
} ⟨a, ⌊a÷n⟩;
𝕨 𝕊 𝕩: 𝕨 𝕊 𝕩‿1E¯5
}
•Show 3 Root 5
•Show 3 Root1 5
•Show 3 Root2 5
•Show 3 Root2 5‿1E¯16
1.7099759466766968
1.7099759466766968
1.7099759641072136
1.709975946676697
Bracmat
Until 2023, Bracmat did not have floating point numbers as primitive type. Instead we had to use rational numbers. This code is not fast!
( ( root
= n a d x0 x1 d2 rnd 10-d
. ( rnd { For 'rounding' rational numbers = keep number of digits within bounds. }
= N r
. !arg:(?N.?r)
& div$(!N*!r+1/2.1)*!r^-1
)
& !arg:(?n,?a,?d)
& !a*!n^-1:?x0
& 10^(-1*!d):?10-d
& whl
' ( ( rnd$(((!n+-1)*!x0+!a*!x0^(1+-1*!n))*!n^-1.10^!d)
. !x0
)
: (?x0.?x1)
& (!x0+-1*!x1)^2:~<!10-d { Exit loop when required precision is reached. }
)
& flt$(!x0,!d) { Convert rational number to floating point representation. }
)
& ( show
= N A precision
. !arg:(?N,?A,?precision)
& out$(str$(!A "^(" !N^-1 ")=" root$(!N,!A,!precision)))
)
& show$(10,1024,20)
& show$(3,27,20)
& show$(2,2,100)
& show$(125,5642,20)
)
Output:
1024^(1/10)=2,00000000000000000000*10E0 27^(1/3)=3,00000000000000000000*10E0 2^(1/2)=1,4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727*10E0 5642^(1/125)=1,07154759194476751170*10E0
This is a floating point reimplementation of the C solution:
"The body of Pow will be compiled twice: once as the the code hidden in the
UFP object called 'POW' (see below) and once as a local function of the code
hidden in the UFP object called 'Root' (also see below)."
& ( Pow
= (s.x) (s.e)
. 1:?r
& 0:?i
& whl
' ( !i:<!e
& !x*!r:?r
& 1+!i:?i
)
& !r
)
& "The next expression is a macro expression that expands $Pow to the body of
the Pow function defined above.
There is another local function, called 'even'."
&
' ( (s.n) (s.x)
. (Pow=$Pow)
& ( even
= (s.v)
. floor$(!v*1/2):?v/2
& subtract$(!v,2*!v/2)
)
& ( !x:0
| ( !n:<1
| !x:<0&even$!n:0
)
& divide$(0,0)
| 0x1p-52*10:?EPS
& 0x1p-52*-10:?EPS-
& 1:?r
& !n+-1:?n-1
& whl
' ( divide
$ (divide$(!x,Pow$(!r,!n-1))+-1*!r,!n)
: ?d
& !d+!r:?r
& (!d:~<!EPS|!d:~>!EPS-)
)
& !r
)
)
: (=?root)
& "Create two UFP objects, POW and ROOT. They are each others' inverse."
& new$(UFP,Pow):?POW
& new$(UFP,root):?Root
& 15:?n
& (POW..go)$("-3.14159",15):?x
& out$((Root..go)$(!n,!x));
Output:
-3.1415899999999999E+00
C
Implemented without using math library, because if we were to use pow()
, the whole exercise wouldn't make sense.
#include <stdio.h>
#include <float.h>
double pow_ (double x, int e) {
int i;
double r = 1;
for (i = 0; i < e; i++) {
r *= x;
}
return r;
}
double root (int n, double x) {
double d, r = 1;
if (!x) {
return 0;
}
if (n < 1 || (x < 0 && !(n&1))) {
return 0.0 / 0.0; /* NaN */
}
do {
d = (x / pow_(r, n - 1) - r) / n;
r += d;
}
while (d >= DBL_EPSILON * 10 || d <= -DBL_EPSILON * 10);
return r;
}
int main () {
int n = 15;
double x = pow_(-3.14159, 15);
printf("root(%d, %g) = %g\n", n, x, root(n, x));
return 0;
}
C#
Almost exactly how C works.
static void Main(string[] args)
{
Console.WriteLine(NthRoot(81,2,.001));
Console.WriteLine(NthRoot(1000,3,.001));
Console.ReadLine();
}
public static double NthRoot(double A,int n, double p)
{
double _n= (double) n;
double[] x = new double[2];
x[0] = A;
x[1] = A/_n;
while(Math.Abs(x[0] -x[1] ) > p)
{
x[1] = x[0];
x[0] = (1/_n)*(((_n-1)*x[1]) + (A/Math.Pow(x[1],_n-1)));
}
return x[0];
}
C++
double NthRoot(double m_nValue, double index, double guess, double pc)
{
double result = guess;
double result_next;
do
{
result_next = (1.0/index)*((index-1.0)*result+(m_nValue)/(pow(result,(index-1.0))));
result = result_next;
pc--;
}while(pc>1);
return result;
};
double NthRoot(double value, double degree)
{
return pow(value, (double)(1 / degree));
};
Clojure
(ns test-project-intellij.core
(:gen-class))
;; define abs & power to avoid needing to bring in the clojure Math library
(defn abs [x]
" Absolute value"
(if (< x 0) (- x) x))
(defn power [x n]
" x to power n, where n = 0, 1, 2, ... "
(apply * (repeat n x)))
(defn calc-delta [A x n]
" nth rooth algorithm delta calculation "
(/ (- (/ A (power x (- n 1))) x) n))
(defn nth-root
" nth root of algorithm: A = numer, n = root"
([A n] (nth-root A n 0.5 1.0)) ; Takes only two arguments A, n and calls version which takes A, n, guess-prev, guess-current
([A n guess-prev guess-current] ; version take takes in four arguments (A, n, guess-prev, guess-current)
(if (< (abs (- guess-prev guess-current)) 1e-6)
guess-current
(recur A n guess-current (+ guess-current (calc-delta A guess-current n)))))) ; iterate answer using tail recursion
COBOL
IDENTIFICATION DIVISION.
PROGRAM-ID. Nth-Root.
AUTHOR. Bill Gunshannon.
INSTALLATION.
DATE-WRITTEN. 4 Feb 2020.
************************************************************
** Program Abstract:
** Compute the Nth Root of a positive real number.
**
** Takes values from console. If Precision is left
** blank defaults to 0.001.
**
** Enter 0 for first value to terminate program.
************************************************************
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT Root-File ASSIGN TO "Root-File"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD Root-File
DATA RECORD IS Parameters.
01 Parameters.
05 Root PIC 9(5).
05 Num PIC 9(5)V9(5).
05 Precision PIC 9V9(9).
WORKING-STORAGE SECTION.
01 TEMP0 PIC 9(9)V9(9).
01 TEMP1 PIC 9(9)V9(9).
01 RESULTS.
05 Field1 PIC ZZZZZ.ZZZZZ.
05 FILLER PIC X(5).
05 Field2 PIC ZZZZ9.
05 FILLER PIC X(14).
05 Field3 PIC 9.999999999.
01 HEADER.
05 FILLER PIC X(72)
VALUE " Number Root Precision.".
01 Disp-Root PIC ZZZZZ.ZZZZZ.
PROCEDURE DIVISION.
Main-Program.
PERFORM FOREVER
PERFORM Get-Input
IF Precision = 0.0
THEN MOVE 0.001 to Precision
END-IF
PERFORM Compute-Root
MOVE Root TO Field2
MOVE Num TO Field1
MOVE Precision TO Field3
DISPLAY HEADER
DISPLAY RESULTS
DISPLAY " "
MOVE TEMP1 TO Disp-Root
DISPLAY "The Root is: " Disp-Root
END-PERFORM.
Get-Input.
DISPLAY "Input Base Number: " WITH NO ADVANCING
ACCEPT Num
IF Num EQUALS ZERO
THEN
DISPLAY "Good Bye."
STOP RUN
END-IF
DISPLAY "Input Root: " WITH NO ADVANCING
ACCEPT Root
DISPLAY "Input Desired Precision: " WITH NO ADVANCING
ACCEPT Precision.
Compute-Root.
MOVE Root TO TEMP0
DIVIDE Num BY Root GIVING TEMP1
PERFORM UNTIL FUNCTION ABS(TEMP0 - TEMP1)
LESS THAN Precision
MOVE TEMP1 TO TEMP0
COMPUTE TEMP1 = (( Root - 1.0) * TEMP1 + Num /
TEMP1 ** (Root - 1.0)) / Root
END-PERFORM.
END-PROGRAM.
- Output:
Input Base Number: 25.0 Input Root: 2 Input Desired Precision: 0.0001 Root Number Precision. 25.00000 2 0.000100000 The Root is: 5.00000 Input Base Number: 5642.0 Input Root: 125 Input Desired Precision: Root Number Precision. 5642.00000 125 0.001000000 The Root is: 1.07155 Input Base Number: 0 Good Bye.
CoffeeScript
nth_root = (A, n, precision=0.0000000000001) ->
x = 1
while true
x_new = (1 / n) * ((n - 1) * x + A / Math.pow(x, n - 1))
return x_new if Math.abs(x_new - x) < precision
x = x_new
# tests
do ->
tests = [
[8, 3]
[16, 4]
[32, 5]
[343, 3]
[1024, 10]
[1000000000, 3]
[1000000000, 9]
[100, 2]
[100, 3]
[100, 5]
[100, 10]
]
for test in tests
[x, n] = test
root = nth_root x, n
console.log "#{x} root #{n} = #{root} (root^#{n} = #{Math.pow root, n})"
output
> coffee nth_root.coffee
8 root 3 = 2 (root^3 = 8)
16 root 4 = 2 (root^4 = 16)
32 root 5 = 2 (root^5 = 32)
343 root 3 = 7 (root^3 = 343)
1024 root 10 = 2 (root^10 = 1024)
1000000000 root 3 = 1000 (root^3 = 1000000000)
1000000000 root 9 = 10 (root^9 = 1000000000)
100 root 2 = 10 (root^2 = 100)
100 root 3 = 4.641588833612778 (root^3 = 99.99999999999997)
100 root 5 = 2.5118864315095806 (root^5 = 100.0000000000001)
100 root 10 = 1.5848931924611134 (root^10 = 99.99999999999993)
Common Lisp
This version does not check for cycles in xi and xi+1, but finishes when the difference between them drops below ε. The initial guess can be provided, but defaults to n-1.
(defun nth-root (n a &optional (epsilon .0001) (guess (1- n)))
(assert (and (> n 1) (> a 0)))
(flet ((next (x)
(/ (+ (* (1- n) x)
(/ a (expt x (1- n))))
n)))
(do* ((xi guess xi+1)
(xi+1 (next xi) (next xi)))
((< (abs (- xi+1 xi)) epsilon) xi+1))))
nth-root
may return rationals rather than floating point numbers, so easy checking for correctness may require coercion to floats. For instance,
(let* ((r (nth-root 3 10))
(rf (coerce r 'float)))
(print (* r r r ))
(print (* rf rf rf)))
produces the following output.
1176549099958810982335712173626176/117654909634627320192156007194483 10.0
D
import std.stdio, std.math;
real nthroot(in int n, in real A, in real p=0.001) pure nothrow {
real[2] x = [A, A / n];
while (abs(x[1] - x[0]) > p)
x = [x[1], ((n - 1) * x[1] + A / (x[1] ^^ (n-1))) / n];
return x[1];
}
void main() {
writeln(nthroot(10, 7131.5 ^^ 10));
writeln(nthroot(6, 64));
}
- Output:
7131.5 2
Dart
import 'dart:math' show pow;
num nroot(num value, num degree) {
return pow(value, (1 / degree));
}
void main() {
int n = 15;
num x = pow(-3.14159, 15);
print('root($n, $x) = ${nroot(n, x)}');
}
Delphi
USES
Math;
function NthRoot(A, Precision: Double; n: Integer): Double;
var
x_p, X: Double;
begin
x_p := Sqrt(A);
while Abs(A - Power(x_p, n)) > Precision do
begin
x := (1/n) * (((n-1) * x_p) + (A/(Power(x_p, n - 1))));
x_p := x;
end;
Result := x_p;
end;
E
Rather than choosing an arbitrary precision, this implementation continues until a cycle in the iterated result is found, thus producing an answer almost as precise as the number type.
(Disclaimer: This was not written by a numerics expert; there may be reasons this is a bad idea. Also, it might be that cycles are always of length 2, which would reduce the amount of calculation needed by 2/3.)
def nthroot(n, x) {
require(n > 1 && x > 0)
def np := n - 1
def iter(g) { return (np*g + x/g**np) / n }
var g1 := x
var g2 := iter(g1)
while (!(g1 <=> g2)) {
g1 := iter(g1)
g2 := iter(iter(g2))
}
return g1
}
EasyLang
func power x n .
r = 1
for i = 1 to n
r *= x
.
return r
.
func nth_root x n .
r = 2
repeat
p = power r (n - 1)
d = (x / p - r) / n
r += d
until abs d < 0.0001
.
return r
.
numfmt 4 0
x = power 3.1416 10
print nth_root x 10
Elixir
defmodule RC do
def nth_root(n, x, precision \\ 1.0e-5) do
f = fn(prev) -> ((n - 1) * prev + x / :math.pow(prev, (n-1))) / n end
fixed_point(f, x, precision, f.(x))
end
defp fixed_point(_, guess, tolerance, next) when abs(guess - next) < tolerance, do: next
defp fixed_point(f, _, tolerance, next), do: fixed_point(f, next, tolerance, f.(next))
end
Enum.each([{2, 2}, {4, 81}, {10, 1024}, {1/2, 7}], fn {n, x} ->
IO.puts "#{n} root of #{x} is #{RC.nth_root(n, x)}"
end)
- Output:
2 root of 2 is 1.4142135623746899 4 root of 81 is 3.0 10 root of 1024 is 2.00000000022337 0.5 root of 7 is 48.99999999999993
Erlang
Done by finding the fixed point of a function, which aims to find a value of x for which f(x)=x:
fixed_point(F, Guess, Tolerance) ->
fixed_point(F, Guess, Tolerance, F(Guess)).
fixed_point(_, Guess, Tolerance, Next) when abs(Guess - Next) < Tolerance ->
Next;
fixed_point(F, _, Tolerance, Next) ->
fixed_point(F, Next, Tolerance, F(Next)).
The nth root function algorithm defined on the wikipedia page linked above can advantage of this:
nth_root(N, X) -> nth_root(N, X, 1.0e-5).
nth_root(N, X, Precision) ->
F = fun(Prev) -> ((N - 1) * Prev + X / math:pow(Prev, (N-1))) / N end,
fixed_point(F, X, Precision).
Excel
This will work in any spreadsheet that uses Excel-compatible expressions -- i.e. KOffice's KCells (formerly KSpread), Calligra Tables, and OpenOffice.org Calc.
Beside the obvious;
=A1^(1/B1)
- Cell A1 is the base.
- Cell B1 is the exponent.
- Cell A2 is the first guess (any non-zero number will do).
In cell A3, enter this formula:
=((($B$1-1)*A2)+($A$1/(A2^($B$1-1))))/$B$1
Copy A3 down until you get 2 cells with the same value. (Once there are two visibly-identical cells, all cells below those two will also be identical.)
For example, here we calculate the cube root of 100:
A | B | |
1 | 100 | 3 |
2 | 7 | (first guess) |
3 | 5.346938776 | |
4 | 4.730544697 | |
5 | 4.643251125 | |
6 | 4.641589429 | |
7 | 4.641588834 | |
8 | 4.641588834 |
Alternately, Excel could use the BASIC example above as VBA code, deleting A2 and replacing A3's formula with something like this:
=RootX(A1,B1,.00000001)
F#
let nthroot n A =
let rec f x =
let m = n - 1.
let x' = (m * x + A/x**m) / n
match abs(x' - x) with
| t when t < abs(x * 1e-9) -> x'
| _ -> f x'
f (A / double n)
[<EntryPoint>]
let main args =
if args.Length <> 2 then
eprintfn "usage: nthroot n A"
exit 1
let (b, n) = System.Double.TryParse(args.[0])
let (b', A) = System.Double.TryParse(args.[1])
if (not b) || (not b') then
eprintfn "error: parameter must be a number"
exit 1
printf "%A" (nthroot n A)
0
Compiled using fsc nthroot.fs example output:
nthroot 0.5 7 49.0
Factor
USING: kernel locals math math.functions prettyprint ;
:: th-root ( a n -- a^1/n )
a [
a over n 1 - ^ /f
over n 1 - *
+ n /f
swap over 1e-5 ~ not
] loop ;
34 5 th-root . ! 2.024397458499888
34 5 recip ^ . ! 2.024397458499888
Forth
: th-root { F: a F: n -- a^1/n }
a
begin
a fover n 1e f- f** f/
fover n 1e f- f*
f+ n f/
fswap fover 1e-5 f~
until ;
34e 5e th-root f. \ 2.02439745849989
34e 5e 1/f f** f. \ 2.02439745849989
Fortran
program NthRootTest
implicit none
print *, nthroot(10, 7131.5**10)
print *, nthroot(5, 34.0)
contains
function nthroot(n, A, p)
real :: nthroot
integer, intent(in) :: n
real, intent(in) :: A
real, intent(in), optional :: p
real :: rp, x(2)
if ( A < 0 ) then
stop "A < 0" ! we handle only real positive numbers
elseif ( A == 0 ) then
nthroot = 0
return
end if
if ( present(p) ) then
rp = p
else
rp = 0.001
end if
x(1) = A
x(2) = A/n ! starting "guessed" value...
do while ( abs(x(2) - x(1)) > rp )
x(1) = x(2)
x(2) = ((n-1.0)*x(2) + A/(x(2) ** (n-1.0)))/real(n)
end do
nthroot = x(2)
end function nthroot
end program NthRootTest
Go
func root(a float64, n int) float64 {
n1 := n - 1
n1f, rn := float64(n1), 1/float64(n)
x, x0 := 1., 0.
for {
potx, t2 := 1/x, a
for b := n1; b > 0; b >>= 1 {
if b&1 == 1 {
t2 *= potx
}
potx *= potx
}
x0, x = x, rn*(n1f*x+t2)
if math.Abs(x-x0)*1e15 < x {
break
}
}
return x
}
The above version is for 64 bit wide floating point numbers. The following uses `math/big` Float to implement this same function with 256 bits of precision.
A set of wrapper functions around the somewhat muddled big math library functions is used to make the main function more readable, and also it was necessary to create a power function (Exp) as the library also lacks this function. The exponent in the limit must be at least one less than the number of bits of precision of the input value or the function will enter an infinite loop!
import "math/big"
func Root(a *big.Float, n uint64) *big.Float {
limit := Exp(New(2), 256)
n1 := n-1
n1f, rn := New(float64(n1)), Div(New(1.0), New(float64(n)))
x, x0 := New(1.0), Zero()
_ = x0
for {
potx, t2 := Div(New(1.0), x), a
for b:=n1; b>0; b>>=1 {
if b&1 == 1 {
t2 = Mul(t2, potx)
}
potx = Mul(potx, potx)
}
x0, x = x, Mul(rn, Add(Mul(n1f, x), t2) )
if Lesser(Mul(Abs(Sub(x, x0)), limit), x) { break }
}
return x
}
func Abs(a *big.Float) *big.Float {
return Zero().Abs(a)
}
func Exp(a *big.Float, e uint64) *big.Float {
result := Zero().Copy(a)
for i:=uint64(0); i<e-1; i++ {
result = Mul(result, a)
}
return result
}
func New(f float64) *big.Float {
r := big.NewFloat(f)
r.SetPrec(256)
return r
}
func Div(a, b *big.Float) *big.Float {
return Zero().Quo(a, b)
}
func Zero() *big.Float {
r := big.NewFloat(0.0)
r.SetPrec(256)
return r
}
func Mul(a, b *big.Float) *big.Float {
return Zero().Mul(a, b)
}
func Add(a, b *big.Float) *big.Float {
return Zero().Add(a, b)
}
func Sub(a, b *big.Float) *big.Float {
return Zero().Sub(a, b)
}
func Lesser(x, y *big.Float) bool {
return x.Cmp(y) == -1
}
Groovy
Solution:
import static Constants.tolerance
import static java.math.RoundingMode.HALF_UP
def root(double base, double n) {
double xOld = 1
double xNew = 0
while (true) {
xNew = ((n - 1) * xOld + base/(xOld)**(n - 1))/n
if ((xNew - xOld).abs() < tolerance) { break }
xOld = xNew
}
(xNew as BigDecimal).setScale(7, HALF_UP)
}
Test:
class Constants {
static final tolerance = 0.00001
}
print '''
Base Power Calc'd Root Actual Root
------- ------ ----------- -----------
'''
def testCases = [
[b:32.0, n:5.0, r:2.0],
[b:81.0, n:4.0, r:3.0],
[b:Math.PI**2, n:4.0, r:Math.PI**(0.5)],
[b:7.0, n:0.5, r:49.0],
]
testCases.each {
def r = root(it.b, it.n)
printf('%7.4f %6.4f %11.4f %11.4f\n',
it.b, it.n, r, it.r)
assert (r - it.r).abs() <= tolerance
}
Output:
Base Power Calc'd Root Actual Root ------- ------ ----------- ----------- 32.0000 5.0000 2.0000 2.0000 81.0000 4.0000 3.0000 3.0000 9.8696 4.0000 1.7725 1.7725 7.0000 0.5000 49.0000 49.0000
Haskell
Function exits when there's no difference between two successive values.
n `nthRoot` x = fst $ until (uncurry(==)) (\(_,x0) -> (x0,((n-1)*x0+x/x0**(n-1))/n)) (x,x/n)
Use:
*Main> 2 `nthRoot` 2 1.414213562373095 *Main> 5 `nthRoot` 34 2.024397458499885 *Main> 10 `nthRoot` (734^10) 734.0 *Main> 0.5 `nthRoot` 7 49.0
Or, in applicative terms, with formatted output:
nthRoot :: Double -> Double -> Double
nthRoot n x =
fst $
until
(uncurry (==))
(((,) <*> ((/ n) . ((+) . (pn *) <*> (x /) . (** pn)))) . snd)
(x, x / n)
where
pn = pred n
-------------------------- TESTS --------------------------
main :: IO ()
main =
putStrLn $
fTable
"Nth roots:"
(\(a, b) -> show a ++ " `nthRoot` " ++ show b)
show
(uncurry nthRoot)
[(2, 2), (5, 34), (10, 734 ^ 10), (0.5, 7)]
-------------------- FORMAT OF RESULTS --------------------
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
fTable s xShow fxShow f xs =
let w = maximum (length . xShow <$> xs)
rjust n c = drop . length <*> (replicate n c ++)
in unlines $
s : fmap (((++) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs
- Output:
Nth roots: 2.0 `nthRoot` 2.0 -> 1.414213562373095 5.0 `nthRoot` 34.0 -> 2.0243974584998847 10.0 `nthRoot` 4.539004352165717e28 -> 734.0 0.5 `nthRoot` 7.0 -> 49.0
HicEst
WRITE(Messagebox) NthRoot(5, 34)
WRITE(Messagebox) NthRoot(10, 7131.5^10)
FUNCTION NthRoot(n, A)
REAL :: prec = 0.001
IF( (n > 0) * (A > 0) ) THEN
NthRoot = A / n
DO i = 1, 1/prec
x = ((n-1)*NthRoot + A/(NthRoot^(n-1))) / n
IF( ABS(x - NthRoot) <= prec ) THEN
RETURN
ENDIF
NthRoot = x
ENDDO
ENDIF
WRITE(Messagebox, Name) 'Cannot solve problem for:', prec, n, A
END
Icon and Unicon
All Icon/Unicon reals are double precision.
Output:
3-th root of 125 = 5.0 3-th root of 27 = 3.0 10-th root of 1024 = 2.0 4-th root of 39.0625 = 2.5 10-th root of 3.402584077894253e+038 = 7131.5
J
J has a built in Nth root primitive, %:. For example, 7131.5 = 10 %: 7131.5^10. Also, the exponentiation primitive supports exponents < 1, e.g. 7131.5 = (7131.5^10)^(1%10).
But, since the talk page discourages using built-in facilities, here is a reimplementation, using the E algorithm:
'`N X NP' =. (0 { [)`(1 { [)`(2 { [)
iter =. N %~ (NP * ]) + X % ] ^ NP
nth_root =: (, , _1+[) iter^:_ f. ]
10 nth_root 7131.5^10
7131.5
Java
public static double nthroot(int n, double A) {
return nthroot(n, A, .001);
}
public static double nthroot(int n, double A, double p) {
if(A < 0) {
System.err.println("A < 0");// we handle only real positive numbers
return -1;
} else if(A == 0) {
return 0;
}
double x_prev = A;
double x = A / n; // starting "guessed" value...
while(Math.abs(x - x_prev) > p) {
x_prev = x;
x = ((n - 1.0) * x + A / Math.pow(x, n - 1.0)) / n;
}
return x;
}
public static double nthroot(int n, double x) {
assert (n > 1 && x > 0);
int np = n - 1;
double g1 = x;
double g2 = iter(g1, np, n, x);
while (g1 != g2) {
g1 = iter(g1, np, n, x);
g2 = iter(iter(g2, np, n, x), np, n, x);
}
return g1;
}
private static double iter(double g, int np, int n, double x) {
return (np * g + x / Math.pow(g, np)) / n;
}
JavaScript
Gives the n:nth root of num, with precision prec. (n defaults to 2 [e.g. sqrt], prec defaults to 12.)
function nthRoot(num, nArg, precArg) {
var n = nArg || 2;
var prec = precArg || 12;
var x = 1; // Initial guess.
for (var i=0; i<prec; i++) {
x = 1/n * ((n-1)*x + (num / Math.pow(x, n-1)));
}
return x;
}
jq
# An iterative algorithm for finding: self ^ (1/n) to the given
# absolute precision if "precision" > 0, or to within the precision
# allowed by IEEE 754 64-bit numbers.
# The following implementation handles underflow caused by poor estimates.
def iterative_nth_root(n; precision):
def abs: if . < 0 then -. else . end;
def sq: .*.;
def pow(p): . as $in | reduce range(0;p) as $i (1; . * $in);
def _iterate: # state: [A, x1, x2, prevdelta]
.[0] as $A | .[1] as $x1 | .[2] as $x2 | .[3] as $prevdelta
| ( $x2 | pow(n-1)) as $power
| if $power <= 2.155094094640383e-309
then [$A, $x1, ($x1 + $x2)/2, n] | _iterate
else (((n-1)*$x2 + ($A/$power))/n) as $x1
| (($x1 - $x2)|abs) as $delta
| if (precision == 0 and $delta == $prevdelta and $delta < 1e-15)
or (precision > 0 and $delta <= precision) or $delta == 0 then $x1
else [$A, $x2, $x1, $delta] | _iterate
end
end
;
if n == 1 then .
elif . == 0 then 0
elif . < 0 then error("iterative_nth_root: input \(.) < 0")
elif n != (n|floor) then error("iterative_nth_root: argument \(n) is not an integer")
elif n == 0 then error("iterative_nth_root(0): domain error")
elif n < 0 then 1/iterative_nth_root(-n; precision)
else [., ., (./n), n, 0] | _iterate
end
;
Example: Compare the results of iterative_nth_root and nth_root implemented using builtins
def demo(x):
def nth_root(n): log / n | exp;
def lpad(n): tostring | (n - length) * " " + .;
. as $in
| "\(x)^(1/\(lpad(5))): \(x|nth_root($in)|lpad(18)) vs \(x|iterative_nth_root($in; 1e-10)|lpad(18)) vs \(x|iterative_nth_root($in; 0))"
;
# 5^m for various values of n:
"5^(1/ n): builtin precision=1e-10 precision=0",
( (1,-5,-3,-1,1,3,5,1000,10000) | demo(5))
- Output:
$ jq -n -r -f nth_root_machine_precision.jq
5^(1/ n): builtin precision=1e-10 precision=0
5^(1/ 1): 4.999999999999999 vs 5 vs 5
5^(1/ -5): 0.7247796636776955 vs 0.7247796636776956 vs 0.7247796636776955
5^(1/ -3): 0.5848035476425733 vs 0.5848035476425731 vs 0.5848035476425731
5^(1/ -1): 0.2 vs 0.2 vs 0.2
5^(1/ 1): 4.999999999999999 vs 5 vs 5
5^(1/ 3): 1.709975946676697 vs 1.709975946676697 vs 1.709975946676697
5^(1/ 5): 1.3797296614612147 vs 1.3797296614612147 vs 1.379729661461215
5^(1/ 1000): 1.0016107337527294 vs 1.0016107337527294 vs 1.0016107337527294
5^(1/10000): 1.0001609567433902 vs 1.0001609567433902 vs 1.0001609567433902
Julia
Julia has a built-in exponentiation function A^(1 / n)
, but the specification calls for us to use Newton's method (which we iterate until the limits of machine precision are reached):
function nthroot(n::Integer, r::Real)
r < 0 || n == 0 && throw(DomainError())
n < 0 && return 1 / nthroot(-n, r)
r > 0 || return 0
x = r / n
prevdx = r
while true
y = x ^ (n - 1)
dx = (r - y * x) / (n * y)
abs(dx) ≥ abs(prevdx) && return x
x += dx
prevdx = dx
end
end
@show nthroot.(-5:2:5, 5.0)
@show nthroot.(-5:2:5, 5.0) - 5.0 .^ (1 ./ (-5:2:5))
- Output:
nthroot.(-5:2:5, 5.0) = [0.7247796636776955, 0.5848035476425731, 0.2, 5.0, 1.709975946676697, 1.379729661461215] nthroot.(-5:2:5, 5.0) - 5.0 .^ (1 ./ (-5:2:5)) = [0.0, -1.1102230246251565e-16, 0.0, 0.0, 0.0, 0.0]
Kotlin
// version 1.0.6
fun nthRoot(x: Double, n: Int): Double {
if (n < 2) throw IllegalArgumentException("n must be more than 1")
if (x <= 0.0) throw IllegalArgumentException("x must be positive")
val np = n - 1
fun iter(g: Double) = (np * g + x / Math.pow(g, np.toDouble())) / n
var g1 = x
var g2 = iter(g1)
while (g1 != g2) {
g1 = iter(g1)
g2 = iter(iter(g2))
}
return g1
}
fun main(args: Array<String>) {
val numbers = arrayOf(1728.0 to 3, 1024.0 to 10, 2.0 to 2)
for (number in numbers)
println("${number.first} ^ 1/${number.second}\t = ${nthRoot(number.first, number.second)}")
}
- Output:
1728.0 ^ 1/3 = 12.0 1024.0 ^ 1/10 = 2.0 2.0 ^ 1/2 = 1.414213562373095
Lambdatalk
Translation of Scheme
{def root
{def good-enough? {lambda {next guess tol}
{< {abs {- next guess}} tol} }}
{def improve {lambda {guess num deg}
{/ {+ {* {- deg 1} guess}
{/ num {pow guess {- deg 1}}}} deg} }}
{def *root {lambda {guess num deg tol}
{let { {guess guess} {num num} {deg deg} {tol tol}
{next {improve guess num deg}}
} {if {good-enough? next guess tol}
then guess
else {*root next num deg tol}} }}}
{lambda {num deg tol}
{*root 1.0 num deg tol} }}
-> root
{root {pow 2 10} 10 0.1}
-> 2.0473293223683866
{root {pow 2 10} 10 0.01}
-> 2.004632048354822
{root {pow 2 10} 10 0.001}
-> 2.000047868581671
langur
Langur has a root operator. Here, we show use of both the root operator and an nth root function.
writeln "operator"
writeln (7131.5 ^ 10) ^/ 10
writeln 64 ^/ 6
writeln()
val .nthroot = fn(.n, .A, .p) {
var .x = [.A, .A / .n]
while abs(.x[2]-.x[1]) > .p {
.x = [.x[2], ((.n-1) x .x[2] + .A / (.x[2] ^ (.n-1))) / .n]
}
simplify .x[2]
}
# To make the example from the D language work, we set a low maximum for the number of digits after a decimal point in division.
mode divMaxScale = 7
writeln "function"
writeln .nthroot(10, 7131.5 ^ 10, 0.001)
writeln .nthroot(6, 64, 0.001)
- Output:
operator 7131.5 2 function 7131.5 2
Lingo
on nthRoot (x, root)
return power(x, 1.0/root)
end
the floatPrecision = 8 -- only about display/string cast of floats
put nthRoot(4, 4)
-- 1.41421356
Logo
to about :a :b
output and [:a - :b < 1e-5] [:a - :b > -1e-5]
end
to root :n :a [:guess :a]
localmake "next ((:n-1) * :guess + :a / power :guess (:n-1)) / n
if about :guess :next [output :next]
output (root :n :a :next)
end
show root 5 34 ; 2.02439745849989
Lua
function nroot(root, num)
return num^(1/root)
end
M2000 Interpreter
Using stack statements PUSH, READ, OVER, SHIFT, DROP, NUMBER, FLUSH
Flush empty stack Over 2 copy 2nd as new top (so 2nd now is 3rd) Over 2,2 repeat Over 2 two times. Shift 2 send top to 2nd, and 2nd to top (1st) (there is a SHFITBACK to revesre action) Drop drop top Number get top if is number, else raise error Read, read a variable form top. Functions parameters works with a read too Function Root { Read a, n%, d as double=1.e-4 ...... } because we can send any type and number if function, interpreter can make conversions if we declare that, or if it not possible (no conversion done to a numeric variable if a string is in top of stack) we get an error. Also if we send less values, and we didn't initialize variable before, we get error too. Here we need to flush stack for other parameters if from an error anyone put more arguments. (interpreter never count before call a user function, except for calling events by using event object, so there there is a signature to follow) n% is double inside.
Module Checkit {
Function Root (a, n%, d as double=1.e-4) {
if n%=0 then Error "Division by zero: 1/0"
if a<=0 then Error "Negative or zero number"
if n%=1 then = a : exit
Flush
n2=1-1/n%:a/=n%:n%--:Push a
{ Push 1: For i=1 to n% {Over 2 :Push Number*Number}
Over 2 : Push n2*Number + a/Number
Shift 2: Over 2, 2 :if Abs(Number-Number)>d Then loop
Drop
} Read a : = a
}
Print "square root single"
Print root(1.3346767~, 2, 1.e-9)
Print "square double"
Print root(1.3346767, 2, 1.e-9)
Print "square root decimal"
Print root(1.3346767@, 2, 1.e-9)
Print "internal square root, double"
Print 1.3346767^(1/2)
Print sqrt(1.3346767)
}
Checkit
Maple
The root
command performs this task.
root(1728, 3);
root(1024, 10);
root(2.0, 2);
Output:
12 2 1.414213562
Mathematica/Wolfram Language
Root[A,n]
MATLAB
function answer = nthRoot(number,root)
format long
answer = number / root;
guess = number;
while not(guess == answer)
guess = answer;
answer = (1/root)*( ((root - 1)*guess) + ( number/(guess^(root - 1)) ) );
end
end
Sample Output:
>> nthRoot(2,2)
ans =
1.414213562373095
Maxima
nth_root(a, n) := block(
[x, y, d, p: fpprec],
fpprec: p + 10,
x: bfloat(a),
eps: 10.0b0^-p,
y: do (
d: bfloat((a / x^(n - 1) - x) / n),
if abs(d) < eps * x then return(x),
x: x + d
),
fpprec: p,
bfloat(y)
)$
Metafont
Metafont does not use IEEE floating point and we can't go beyond 0.0001 or it will loop forever.
vardef mnthroot(expr n, A) =
x0 := A / n;
m := n - 1;
forever:
x1 := (m*x0 + A/(x0 ** m)) / n;
exitif abs(x1 - x0) < abs(x0 * 0.0001);
x0 := x1;
endfor;
x1
enddef;
primarydef n nthroot A = mnthroot(n, A) enddef;
show 5 nthroot 34; % 2.0244
show 0.5 nthroot 7; % 49.00528
bye
МК-61/52
1/x <-> x^y С/П
Instruction: number ^ degree В/О С/П
NetRexx
/*NetRexx program to calculate the Nth root of X, with DIGS accuracy. */
class nth_root
method main(args=String[]) static
if args.length < 2 then
do
say "at least 2 arguments expected"
exit
end
x = args[0]
root = args[1]
if args.length > 2 then digs = args[2]
if root=='' then root=2
if digs = null, digs = '' then digs=20
numeric digits digs
say ' x = ' x
say ' root = ' root
say 'digits = ' digs
say 'answer = ' root(x,root,digs)
method root(x,r,digs) static --procedure; parse arg x,R 1 oldR /*assign 2nd arg-->r and rOrig. */
/*this subroutine will use the */
/*digits from the calling prog. */
/*The default digits is 9. */
R = r
oldR = r
if r=0 then do
say
say '*** error! ***'
say "a root of zero can't be specified."
say
return '[n/a]'
end
R=R.abs() /*use absolute value of root. */
if x<0 & (R//2==0) then do
say
say '*** error! ***'
say "an even root can't be calculated for a" -
'negative number,'
say 'the result would be complex.'
say
return '[n/a]'
end
if x=0 | r=1 then return x/1 /*handle couple of special cases.*/
Rm1=R-1 /*just a fast version of ROOT-1 */
oldDigs=digs /*get the current number of digs.*/
dm=oldDigs+5 /*we need a little guard room. */
ax=x.abs() /*the absolute value of X. */
g=(ax+1)/r**r /*take a good stab at 1st guess. */
-- numeric fuzz 3 /*fuzz digits for higher roots. */
d=5 /*start with only five digits. */
/*each calc doubles precision. */
loop forever
d=d+d
if d>dm then d = dm /*double the digits, but not>DM. */
numeric digits d /*tell REXX to use D digits. */
old=0 /*assume some kind of old guess. */
loop forever
_=(Rm1*g**R+ax)/R/g**rm1 /*this is the nitty-gritty stuff.*/
if _=g | _=old then leave /*computed close to this before? */
old=g /*now, keep calculation for OLD. */
g=_ /*set calculation to guesstimate.*/
end
if d==dm then leave /*found the root for DM digits ? */
end
_=g*x.sign() /*correct the sign (maybe). */
if oldR<0 then return _=1/_ /*root < 0 ? Reciprocal it is.*/
numeric digits oldDigs /*re-instate the original digits.*/
return _/1 /*normalize the number to digs. */
NewLISP
(define (nth-root n a)
(let ((x1 a)
(x2 (div a n)))
(until (= x1 x2)
(setq x1 x2
x2 (div
(add
(mul x1 (- n 1))
(div a (pow x1 (- n 1))))
n)))
x2))
Nim
import math
proc nthRoot(a: float; n: int): float =
var n = float(n)
result = a
var x = a / n
while abs(result-x) > 1e-15:
x = result
result = (1/n) * (((n-1)*x) + (a / pow(x, n-1)))
echo nthRoot(34.0, 5)
echo nthRoot(42.0, 10)
echo nthRoot(5.0, 2)
Output:
2.024397458499885 1.453198460282268 2.23606797749979
Nu
def "math root" [n] {$in ** (1 / $n)}
1..10 | each {|it|
1..10 | reduce --fold {index: $it} {|root acc|
$acc | insert $"root ($root)" ($it | math root $root | into string --decimals 4 )
}
}
- Output:
╭──────┬───────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬─────────┬─────────┬──────────╮ │ # │ root 1 │ root 2 │ root 3 │ root 4 │ root 5 │ root 6 │ root 7 │ root 8 │ root 9 │ root 10 │ ├──────┼───────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼─────────┼─────────┼──────────┤ │ 1 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ 1.0000 │ │ 2 │ 2.0000 │ 1.4142 │ 1.2599 │ 1.1892 │ 1.1487 │ 1.1225 │ 1.1041 │ 1.0905 │ 1.0801 │ 1.0718 │ │ 3 │ 3.0000 │ 1.7321 │ 1.4422 │ 1.3161 │ 1.2457 │ 1.2009 │ 1.1699 │ 1.1472 │ 1.1298 │ 1.1161 │ │ 4 │ 4.0000 │ 2.0000 │ 1.5874 │ 1.4142 │ 1.3195 │ 1.2599 │ 1.2190 │ 1.1892 │ 1.1665 │ 1.1487 │ │ 5 │ 5.0000 │ 2.2361 │ 1.7100 │ 1.4953 │ 1.3797 │ 1.3077 │ 1.2585 │ 1.2228 │ 1.1958 │ 1.1746 │ │ 6 │ 6.0000 │ 2.4495 │ 1.8171 │ 1.5651 │ 1.4310 │ 1.3480 │ 1.2917 │ 1.2510 │ 1.2203 │ 1.1962 │ │ 7 │ 7.0000 │ 2.6458 │ 1.9129 │ 1.6266 │ 1.4758 │ 1.3831 │ 1.3205 │ 1.2754 │ 1.2414 │ 1.2148 │ │ 8 │ 8.0000 │ 2.8284 │ 2.0000 │ 1.6818 │ 1.5157 │ 1.4142 │ 1.3459 │ 1.2968 │ 1.2599 │ 1.2311 │ │ 9 │ 9.0000 │ 3.0000 │ 2.0801 │ 1.7321 │ 1.5518 │ 1.4422 │ 1.3687 │ 1.3161 │ 1.2765 │ 1.2457 │ │ 10 │ 10.0000 │ 3.1623 │ 2.1544 │ 1.7783 │ 1.5849 │ 1.4678 │ 1.3895 │ 1.3335 │ 1.2915 │ 1.2589 │ ╰──────┴───────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴─────────┴─────────┴──────────╯
Objeck
class NthRoot {
function : Main(args : String[]) ~ Nil {
NthRoot(5, 34, .001)->PrintLine();
}
function : NthRoot(n : Int, A: Float, p : Float) ~ Float {
x := Float->New[2];
x[0] := A;
x[1] := A / n;
while((x[1] - x[0])->Abs() > p) {
x[0] := x[1];
x[1] := ((n - 1.0) * x[1] + A / x[1]->Power(n - 1.0)) / n;
};
return x[1];
}
}
OCaml
let nthroot ~n ~a ?(tol=0.001) () =
let nf = float n in let nf1 = nf -. 1.0 in
let rec iter x =
let x' = (nf1 *. x +. a /. (x ** nf1)) /. nf in
if tol > abs_float (x -. x') then x' else iter x' in
iter 1.0
;;
let () =
Printf.printf "%g\n" (nthroot 10 (7131.5 ** 10.0) ());
Printf.printf "%g\n" (nthroot 5 34.0 ());
;;
Octave
Octave has it's how nthroot function.
r = A.^(1./n)
Here it is another implementation (after Tcl)
function r = m_nthroot(n, A)
x0 = A / n;
m = n - 1;
while(1)
x1 = (m*x0 + A./ x0 .^ m) / n;
if ( abs(x1-x0) < abs(x0 * 1e-9) )
r = x1;
return
endif
x0 = x1;
endwhile
endfunction
Here is an more elegant way by computing the successive differences in an explicit way:
function r = m_nthroot(n, A)
r = A / n;
m = n - 1;
do
d = (A ./ r .^ m - r) / n;
r+= d;
until (abs(d) < abs(r * 1e-9))
endfunction
Show its usage and the built-in nthroot function
m_nthroot(10, 7131.5 .^ 10)
nthroot(7131.5 .^ 10, 10)
m_nthroot(5, 34)
nthroot(34, 5)
m_nthroot(0.5, 7)
nthroot(7, .5)
Oforth
Float method: nthroot(n)
1.0 doWhile: [ self over n 1 - pow / over - n / tuck + swap 0.0 <> ] ;
- Output:
734 10.0 powf nthroot(10) println 734 2.0 nthroot(2) println 1.41421356237309 34.0 nthroot(5) println 2.02439745849989
Oz
declare
fun {NthRoot NInt A}
N = {Int.toFloat NInt}
fun {Next X}
( (N-1.0)*X + A / {Pow X N-1.0} ) / N
end
in
{Until Value.'==' Next A/N}
end
fun {Until P F X}
case {F X}
of NX andthen {P NX X} then X
[] NX then {Until P F NX}
end
end
in
{Show {NthRoot 2 2.0}}
PARI/GP
root(n,A)=A^(1/n);
Pascal
See Delphi
Perl
use strict;
sub nthroot ($$)
{
my ( $n, $A ) = @_;
my $x0 = $A / $n;
my $m = $n - 1.0;
while(1) {
my $x1 = ($m * $x0 + $A / ($x0 ** $m)) / $n;
return $x1 if abs($x1 - $x0) < abs($x0 * 1e-9);
$x0 = $x1;
}
}
print nthroot(5, 34), "\n";
print nthroot(10, 7131.5 ** 10), "\n";
print nthroot(0.5, 7), "\n";
Phix
Main loop copied from AWK, and as per C uses pow_() instead of power() since using the latter would make the whole exercise somewhat pointless.
with javascript_semantics function pow_(atom x, integer e) atom r = 1 for i=1 to e do r *= x end for return r end function function nth_root(atom y, n) atom eps = 1e-15, -- relative accuracy x = 1 while 1 do -- atom d = ( y / power(x,n-1) - x ) / n atom d = ( y / pow_(x,n-1) - x ) / n x += d atom e = eps*x -- absolute accuracy if d > -e and d < e then exit end if end while return x end function procedure test(sequence yn) atom {y,n} = yn printf(1,"nth_root(%d,%d) = %.10g, builtin = %.10g\n",{y,n,nth_root(y,n),power(y,1/n)}) end procedure papply({{1024,10},{27,3},{2,2},{5642,125},{4913,3},{8,3},{16,2},{16,4},{125,3},{1000000000,3},{1000000000,9}},test)
Note that a {7,0.5} test would need to use power() instead of pow_().
- Output:
nth_root(1024,10) = 2, builtin = 2 nth_root(27,3) = 3, builtin = 3 nth_root(2,2) = 1.414213562, builtin = 1.414213562 nth_root(5642,125) = 1.071547592, builtin = 1.071547592 nth_root(4913,3) = 17, builtin = 17 nth_root(8,3) = 2, builtin = 2 nth_root(16,2) = 4, builtin = 4 nth_root(16,4) = 2, builtin = 2 nth_root(125,3) = 5, builtin = 5 nth_root(1000000000,3) = 1000, builtin = 1000 nth_root(1000000000,9) = 10, builtin = 10
Phixmonti
def nthroot
var n var y
1e-15 var eps /# relative accuracy #/
1 var x
true
while
y x n 1 - power / x - n / var d
x d + var x
eps x * var e /# absolute accuracy #/
d 0 e - < d e > or
endwhile
x
enddef
def printList
len for get print endfor
enddef
10 1024 3 27 2 2 125 5642 4 16 stklen tolist
len 1 swap 2 3 tolist
for
var i
i get swap i 1 + get rot var e var b
"The " e "th root of " b " is " b 1 e / power " (" b e nthroot ")" 9 tolist
printList drop nl
endfor
PHP
function nthroot($number, $root, $p = P)
{
$x[0] = $number;
$x[1] = $number/$root;
while(abs($x[1]-$x[0]) > $p)
{
$x[0] = $x[1];
$x[1] = (($root-1)*$x[1] + $number/pow($x[1], $root-1))/$root;
}
return $x[1];
}
Picat
go =>
L = [[2,2],
[34,5],
[34**5,5],
[7131.5**10],
[7,0.5],
[1024,10],
[5642, 125]
],
foreach([A,N] in L)
R = nthroot(A,N),
printf("nthroot(%8w,%8w) %20w (check: %w)\n",A,N,R,A**(1/N))
end,
nl.
%
% x^n = a
%
% Given a and n, find x (to Precision)
%
nthroot(A,N) = nthroot(A,N,0.000001).
nthroot(A,N,Precision) = X1 =>
NF = N * 1.0, % float version of N
X0 = A / NF,
X1 = 1.0,
do
X0 := X1,
X1 := (1.0 / NF)*((NF - 1.0)*X0 + (A / (X0 ** (NF - 1))))
while( abs(X0-X1) > Precision).
- Output:
nthroot( 2, 2) 1.414213562373095 (check: 1.414213562373095) nthroot( 34, 5) 2.024397458499885 (check: 2.024397458499885) nthroot(45435424, 5) 34.0 (check: 34.000000000000007) nthroot( 7, 0.5) 48.999999999999993 (check: 49.0) nthroot( 1024, 10) 2.0 (check: 2.0) nthroot( 5642, 125) 1.071547591944767 (check: 1.071547591944767)
PicoLisp
(load "@lib/math.l")
(de nthRoot (N A)
(let (X1 A X2 (*/ A N))
(until (= X1 X2)
(setq
X1 X2
X2 (*/
(+
(* X1 (dec N))
(*/ A 1.0 (pow X1 (* (dec N) 1.0))) )
N ) ) )
X2 ) )
(prinl (format (nthRoot 2 2.0) *Scl))
(prinl (format (nthRoot 3 12.3) *Scl))
(prinl (format (nthRoot 4 45.6) *Scl))
Output:
1.414214 2.308350 2.598611
PL/I
/* Finds the N-th root of the number A */
root: procedure (A, N) returns (float);
declare A float, N fixed binary;
declare (xi, xip1) float;
xi = 1; /* An initial guess */
do forever;
xip1 = ((n-1)*xi + A/xi**(n-1) ) / n;
if abs(xip1-xi) < 1e-5 then leave;
xi = xip1;
end;
return (xi);
end root;
Results:
The 2-th root of 4.00000E+0000 is 2.00000E+0000 The 5-th root of 3.20000E+0001 is 2.00000E+0000 The 3-th root of 2.70000E+0001 is 3.00000E+0000 The 2-th root of 2.00000E+0000 is 1.41422E+0000 The 3-th root of 1.00000E+0002 is 4.64159E+0000
PowerShell
This sample implementation does not use [System.Math]
classes.
#NoTeS: This sample code does not validate inputs
# Thus, if there are errors the 'scary' red-text
# error messages will appear.
#
# This code will not work properly in floating point values of n,
# and negative values of A.
#
# Supports negative values of n by reciprocating the root.
$epsilon=1E-10 #Sample Epsilon (Precision)
function power($x,$e){ #As I said in the comment
$ret=1
for($i=1;$i -le $e;$i++){
$ret*=$x
}
return $ret
}
function root($y,$n){ #The main Function
if (0+$n -lt 0){$tmp=-$n} else {$tmp=$n} #This checks if n is negative.
$ans=1
do{
$d = ($y/(power $ans ($tmp-1)) - $ans)/$tmp
$ans+=$d
} while ($d -lt -$epsilon -or $d -gt $epsilon)
if (0+$n -lt 0){return 1/$ans} else {return $ans}
}
#Sample Inputs
root 625 2
root 2401 4
root 2 -2
root 1.23456789E-20 34
root 9.87654321E20 10 #Quite slow here, I admit...
((root 5 2)+1)/2 #Extra: Computes the golden ratio
((root 5 2)-1)/2
- Output:
PS> .\NTH.PS1 25 7 0.707106781186548 0.259690655650288 125.736248016373 1.61803398874989 0.618033988749895 PS>
Prolog
Uses integer math, though via scaling, it can approximate non-integral roots to arbitrary precision.
iroot(_, 0, 0) :- !.
iroot(M, N, R) :-
M > 1,
(N > 0 ->
irootpos(M, N, R)
;
N /\ 1 =:= 1,
NegN is -N, irootpos(M, NegN, R0), R is -R0).
irootpos(N, A, R) :-
X0 is 1 << (msb(A) div N), % initial guess is 2^(log2(A) / N)
newton(N, A, X0, X1),
iroot_loop(A, X1, N, A, R).
iroot_loop(X1, X2, _, _, X1) :- X1 =< X2, !.
iroot_loop(_, X1, N, A, R) :-
newton(N, A, X1, X2),
iroot_loop(X1, X2, N, A, R).
newton(2, A, X0, X1) :- X1 is (X0 + A div X0) >> 1, !. % fast special case
newton(N, A, X0, X1) :- X1 is ((N - 1)*X0 + A div X0**(N - 1)) div N.
- Output:
?- iroot(3, 10000, X). X = 21. ?- A is 2**(1/12). % 12-root of 2 via built-in A = 1.0594630943592953. ?- A is 2 * 10**(12 * 15), iroot(12, A, R), format("~15d", [R]). % 12-root of 2 via scaled int 1.059463094359295 A = 2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, R = 1059463094359295. ?- iroot(2, 81, X). X = 9. ?- iroot(4, -256, X). % fails for negative even roots false. ?- iroot(3, -27, X). % succeeds for negative odd roots X = -3.
Python
from decimal import Decimal, getcontext
def nthroot (n, A, precision):
getcontext().prec = precision
n = Decimal(n)
x_0 = A / n #step 1: make a while guess.
x_1 = 1 #need it to exist before step 2
while True:
#step 2:
x_0, x_1 = x_1, (1 / n)*((n - 1)*x_0 + (A / (x_0 ** (n - 1))))
if x_0 == x_1:
return x_1
print nthroot(5, 34, 10)
print nthroot(10,42, 20)
print nthroot(2, 5, 400)
Or, in terms of a general until function:
'''Nth Root'''
from decimal import Decimal, getcontext
from operator import eq
# nthRoot :: Int -> Int -> Int -> Real
def nthRoot(precision):
'''The nth root of x at the given precision.'''
def go(n, x):
getcontext().prec = precision
dcn = Decimal(n)
def same(ab):
return eq(*ab)
def step(ab):
a, b = ab
predn = pred(dcn)
return (
b,
reciprocal(dcn) * (
predn * a + (
x / (a ** predn)
)
)
)
return until(same)(step)(
(x / dcn, 1)
)[0]
return lambda n: lambda x: go(n, x)
# --------------------------TEST---------------------------
def main():
'''Nth roots at various precisions'''
def xShow(tpl):
p, n, x = tpl
return rootName(n) + (
' of ' + str(x) + ' at precision ' + str(p)
)
def f(tpl):
p, n, x = tpl
return nthRoot(p)(n)(x)
print(
fTable(main.__doc__ + ':\n')(xShow)(str)(f)(
[(10, 5, 34), (20, 10, 42), (30, 2, 5)]
)
)
# -------------------------DISPLAY-------------------------
# fTable :: String -> (a -> String) ->
# (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
'''Heading -> x display function -> fx display function ->
f -> xs -> tabular string.
'''
def go(xShow, fxShow, f, xs):
ys = [xShow(x) for x in xs]
w = max(map(len, ys))
return s + '\n' + '\n'.join(map(
lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
xs, ys
))
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
xShow, fxShow, f, xs
)
# -------------------------GENERIC-------------------------
# rootName :: Int -> String
def rootName(n):
'''English ordinal suffix.'''
return ['identity', 'square root', 'cube root'][n - 1] if (
4 > n or 1 > n
) else (str(n) + 'th root')
# pred :: Enum a => a -> a
def pred(x):
'''The predecessor of a value. For numeric types, (- 1).'''
return x - 1
# reciprocal :: Num -> Num
def reciprocal(x):
'''Arithmetic reciprocal of x.'''
return 1 / x
# until :: (a -> Bool) -> (a -> a) -> a -> a
def until(p):
'''The result of repeatedly applying f until p holds.
The initial seed value is x.
'''
def go(f, x):
v = x
while not p(v):
v = f(v)
return v
return lambda f: lambda x: go(f, x)
if __name__ == '__main__':
main()
- Output:
Nth roots at various precisions: 5th root of 34 at precision 10 -> 2.024397458 10th root of 42 at precision 20 -> 1.4531984602822678165 square root of 5 at precision 30 -> 2.23606797749978969640917366873
R
nthroot <- function(A, n, tol=sqrt(.Machine$double.eps))
{
ifelse(A < 1, x0 <- A * n, x0 <- A / n)
repeat
{
x1 <- ((n-1)*x0 + A / x0^(n-1))/n
if(abs(x1 - x0) > tol) x0 <- x1 else break
}
x1
}
nthroot(7131.5^10, 10) # 7131.5
nthroot(7, 0.5) # 49
Racket
#lang racket
(define (nth-root number root (tolerance 0.001))
(define (acceptable? next current)
(< (abs (- next current)) tolerance))
(define (improve current)
(/ (+ (* (- root 1) current) (/ number (expt current (- root 1)))) root))
(define (loop current)
(define next-guess (improve current))
(if (acceptable? next-guess current)
next-guess
(loop next-guess)))
(loop 1.0))
Raku
(formerly Perl 6)
sub infix:<√>($n, $A) {
.tail given $A / $n, { (($n-1) * $_+ $A / ($_** ($n-1))) / $n } ... * ≅ *;
}
use Test;
plan 9;
is-approx ($_√pi)**$_, pi for 2 .. 10;
RATFOR
program nth
#
integer root
real number, precision
real temp0, temp1
1 format('Enter the base number: ')
2 format('Enter the desired root: ')
3 format('Enter the desired precision: ')
4 format(F12.6)
5 format(I6)
write(6,1)
read(5,4)number
write(6,2)
read(5,5)root
write(6,3)
read(5,4)precision
temp0 = number
temp1 = number/root
while ( abs(temp0 - temp1) > precision )
{
temp0 = temp1
temp1 = ((root - 1.0) * temp1 + number / temp1 ** (root - 1.0)) / root
}
6 format(' number root precision')
write(6,6)
7 format(f12.6,i6,f12.6)
write (6,7)number,root,precision
8 format('The root is: ',F12.6)
write (6,8)temp1
end
Results: Enter the base number: 25.0 Enter the desired root: 2 Enter the desired precision: .0001 number root precision 25.000000 2 0.000100 The root is: 5.000000 Enter the base number: 65536.0 Enter the desired root: 16 Enter the desired precision: .0001 number root precision 65536.000000 16 0.000100 The root is: 2.000000
REXX
/*REXX program calculates the Nth root of X, with DIGS (decimal digits) accuracy. */
parse arg x root digs . /*obtain optional arguments from the CL*/
if x=='' | x=="," then x= 2 /*Not specified? Then use the default.*/
if root=='' | root=="," then root= 2 /* " " " " " " */
if digs=='' | digs=="," then digs=65 /* " " " " " " */
numeric digits digs /*set the decimal digits to DIGS. */
say ' x = ' x /*echo the value of X. */
say ' root = ' root /* " " " " ROOT. */
say ' digits = ' digs /* " " " " DIGS. */
say ' answer = ' root(x, root) /*show the value of ANSWER. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
root: procedure; parse arg x 1 Ox, r 1 Or /*arg1 ──► x & Ox, 2nd ──► r & Or*/
if r=='' then r=2 /*Was root specified? Assume √. */
if r=0 then return '[n/a]' /*oops-ay! Can't do zeroth root.*/
complex= x<0 & R//2==0 /*will the result be complex? */
oDigs=digits() /*get the current number of digs.*/
if x=0 | r=1 then return x/1 /*handle couple of special cases.*/
dm=oDigs+5 /*we need a little guard room. */
r=abs(r); x=abs(x) /*the absolute values of R and X.*/
rm=r-1 /*just a fast version of ROOT -1*/
numeric form /*take a good guess at the root─┐*/
parse value format(x,2,1,,0) 'E0' with ? 'E' _ . /* ◄────────────────────────────┘*/
g= (? / r'E'_ % r) + (x>1) /*kinda uses a crude "logarithm".*/
d=5 /*start with five decimal digits.*/
do until d==dm; d=min(d+d,dm) /*each time, precision doubles. */
numeric digits d /*tell REXX to use D digits. */
old=-1 /*assume some kind of old guess. */
do until old=g; old=g /*where da rubber meets da road─┐*/
g=format((rm*g**r+x)/r/g**rm,, d-2) /* ◄────── the root computation─┘*/
end /*until old=g*/ /*maybe until the cows come home.*/
end /*until d==dm*/ /*and wait for more cows to come.*/
if g=0 then return 0 /*in case the jillionth root = 0.*/
if Or<0 then g=1/g /*root < 0 ? Reciprocal it is! */
if \complex then g=g*sign(Ox) /*adjust the sign (maybe). */
numeric digits oDigs /*reinstate the original digits. */
return (g/1) || left('j', complex) /*normalize # to digs, append j ?*/
output when using the default inputs:
x = 2 root = 2 digits = 65 answer = 1.414213562373095048801688724209698078569671875376948073176679738
output when using for input: 10 3
x = 10 root = 3 digits = 65 answer = 2.1544346900318837217592935665193504952593449421921085824892355063
output when using for input: 625 -4
x = 625 root = -4 digits = 65 answer = 0.2
output when using for input: 100.666 47
x = 100.666 root = 47 digits = 65 answer = 1.1030990940616109102886569991014966919115206420386192403152621652
output when using for input: -256 8
x = -256 root = 8 digits = 65 answer = 2j
output when using for input: 12345678900098765432100.00987654321000123456789e333 19
x = 12345678900098765432100.00987654321000123456789e333 root = 19 digits = 65 answer = 4886828567991886455.3257854108687610458584138783288904955196401434
Ring
decimals(12)
see "cube root of 5 is : " + root(3, 5, 0) + nl
func root n, a, d
y = 0 x = a / n
while fabs (x - y) > d
y = ((n - 1)*x + a/pow(x,(n-1))) / n
temp = x
x = y
y = temp
end
return x
Output:
cube root of 5 is : 1.709975946677
RPL
RPL code | Comment |
---|---|
≪ → a n epsilon ≪ a n / DUP DO SWAP DROP a n / OVER INV n 1 - ^ * OVER n 1 - * n / + UNTIL DUP2 - ABS epsilon < END SWAP DROP ≫ ≫ 'NROOT' STO |
( a n error -- a^(1/n) ) Start with x0 = x1 = a/n both in stack Loop: Forget x(k-1) Calculate x(k+1) Exit loop when x(k+1) close to xk Forget xk |
- Input:
5 3 0.000000001 NROOT
- Output:
1: 1.70997594668
Ruby
def nthroot(n, a, precision = 1e-5)
x = Float(a)
begin
prev = x
x = ((n - 1) * prev + a / (prev ** (n - 1))) / n
end while (prev - x).abs > precision
x
end
p nthroot(5,34) # => 2.02439745849989
Rust
// 20210212 Rust programming solution
fn nthRoot(n: f64, A: f64) -> f64 {
let p = 1e-9_f64 ;
let mut x0 = A / n ;
loop {
let mut x1 = ( (n-1.0) * x0 + A / f64::powf(x0, n-1.0) ) / n;
if (x1-x0).abs() < (x0*p).abs() { return x1 };
x0 = x1
}
}
fn main() {
println!("{}", nthRoot(3. , 8. ));
}
Sather
class MATH is
nthroot(n:INT, a:FLT):FLT
pre n > 0
is
x0 ::= a / n.flt;
m ::= n - 1;
loop
x1 ::= (m.flt * x0 + a/(x0^(m.flt))) / n.flt;
if (x1 - x0).abs < (x0 * 1.0e-9).abs then
return x1;
end;
x0 := x1;
end;
end;
end;
class MAIN is
main is
a:FLT := 2.5 ^ 10.0;
#OUT + MATH::nthroot(10, a) + "\n";
end;
end;
Scala
Using tail recursion:
def nroot(n: Int, a: Double): Double = {
@tailrec
def rec(x0: Double) : Double = {
val x1 = ((n - 1) * x0 + a/math.pow(x0, n-1))/n
if (x0 <= x1) x0 else rec(x1)
}
rec(a)
}
Alternatively, you can implement the iteration with an iterator like so:
def fallPrefix(itr: Iterator[Double]): Iterator[Double] = itr.sliding(2).dropWhile(p => p(0) > p(1)).map(_.head)
def nrootLazy(n: Int)(a: Double): Double = fallPrefix(Iterator.iterate(a){r => (((n - 1)*r) + (a/math.pow(r, n - 1)))/n}).next
Scheme
(define (root number degree tolerance)
(define (good-enough? next guess)
(< (abs (- next guess)) tolerance))
(define (improve guess)
(/ (+ (* (- degree 1) guess) (/ number (expt guess (- degree 1)))) degree))
(define (*root guess)
(let ((next (improve guess)))
(if (good-enough? next guess)
guess
(*root next))))
(*root 1.0))
(display (root (expt 2 10) 10 0.1))
(newline)
(display (root (expt 2 10) 10 0.01))
(newline)
(display (root (expt 2 10) 10 0.001))
(newline)
Output:
2.04732932236839 2.00463204835482 2.00004786858167
Seed7
The nth root of the number 'a' can be computed with the exponentiation operator: 'a ** (1 / n)'. An alternate function which uses Newton's method is:
const func float: nthRoot (in integer: n, in float: a) is func
result
var float: x1 is 0.0;
local
var float: x0 is 0.0;
begin
x0 := a;
x1 := a / flt(n);
while abs(x1 - x0) >= abs(x0 * 1.0E-9) do
x0 := x1;
x1 := (flt(pred(n)) * x0 + a / x0 ** pred(n)) / flt(n);
end while;
end func;
Original source: [1]
Sidef
func nthroot(n, a, precision=1e-5) {
var x = 1.float
var prev = 0.float
while ((prev-x).abs > precision) {
prev = x;
x = (((n-1)*prev + a/(prev**(n-1))) / n)
}
return x
}
say nthroot(5, 34) # => 2.024397458501034082599817835297912829678314204
A minor optimization would be to calculate the successive int(n-1) square roots of a number, then raise the result to the power of 2**(int(n-1) / n).
func nthroot_fast(n, a, precision=1e-5) {
{ a = nthroot(2, a, precision) } * int(n-1)
a ** (2**int(n-1) / n)
}
say nthroot_fast(5, 34, 1e-64) # => 2.02439745849988504251081724554193741911462170107
Smalltalk
Number extend [
nthRoot: n [
|x0 m x1|
x0 := (self / n) asFloatD.
m := n - 1.
[true] whileTrue: [
x1 := ( (m * x0) + (self/(x0 raisedTo: m))) / n.
((x1 - x0) abs) < ((x0 * 1e-9) abs)
ifTrue: [ ^ x1 ].
x0 := x1
]
]
].
(34 nthRoot: 5) displayNl.
((7131.5 raisedTo: 10) nthRoot: 10) displayNl.
(7 nthRoot: 0.5) displayNl.
SPL
nthr(n,r) <= n^(1/r)
nthroot(n,r)=
a = n/r
g = n
> g!=a
g = a
a = (1/r)*(((r-1)*g)+(n/(g^(r-1))))
<
<= a
.
#.output(nthr(2,2))
#.output(nthroot(2,2))
- Output:
1.4142135623731 1.41421356237309
Swift
extension FloatingPoint where Self: ExpressibleByFloatLiteral {
@inlinable
public func power(_ e: Int) -> Self {
var res = Self(1)
for _ in 0..<e {
res *= self
}
return res
}
@inlinable
public func root(n: Int, epsilon: Self = 2.220446049250313e-16) -> Self {
var d = Self(0)
var res = Self(1)
guard self != 0 else {
return 0
}
guard n >= 1 else {
return .nan
}
repeat {
d = (self / res.power(n - 1) - res) / Self(n)
res += d
} while d >= epsilon * 10 || d <= -epsilon * 10
return res
}
}
print(81.root(n: 4))
print(13.root(n: 5))
- Output:
3.0 1.6702776523348104
Tcl
The easiest way is to just use the pow
function (or exponentiation operator) like this:
proc nthroot {n A} {
expr {pow($A, 1.0/$n)}
}
However that's hardly tackling the problem itself. So here's how to do it using Newton-Raphson and a self-tuning termination test.
proc nthroot {n A} {
set x0 [expr {$A / double($n)}]
set m [expr {$n - 1.0}]
while 1 {
set x1 [expr {($m*$x0 + $A/$x0**$m) / $n}]
if {abs($x1 - $x0) < abs($x0 * 1e-9)} {
return $x1
}
set x0 $x1
}
}
Demo:
puts [nthroot 2 2]
puts [nthroot 5 34]
puts [nthroot 5 [expr {34**5}]]
puts [nthroot 10 [expr 7131.5**10]]
puts [nthroot 0.5 7]; # Squaring!
Output:
1.414213562373095 2.0243974584998847 34.0 7131.5 49.0
Ursala
The nthroot function defined below takes a natural number n to the function that returns the n-th root of its floating point argument. Error is on the order of machine precision because the stopping criterion is either a fixed point or a repeating cycle.
#import nat
#import flo
nthroot =
-+
("n","n-1"). "A". ("x". div\"n" plus/times("n-1","x") div("A",pow("x","n-1")))^== 1.,
float^~/~& predecessor+-
This implementation is unnecessary in practice due to the availability of the library function pow, which performs exponentiation and allows fractional exponents. Here is a test program.
#cast %eL
examples =
<
nthroot2 2.,
nthroot5 34.,
nthroot5 pow(34.,5.),
nthroot10 pow(7131.5,10.)>
output:
< 1.414214e+00, 2.024397e+00, 3.400000e+01, 7.131500e+03>
V (Vlang)
import math
fn main() {
println("cube root of 5 is: ${math.cbrt(5)}")
}
- Output:
cube root of 5 is: 1.709975946676697
Wren
var nthRoot = Fn.new { |x, n|
if (n < 2) Fiber.abort("n must be more than 1")
if (x <= 0) Fiber.abort("x must be positive")
var np = n - 1
var iter = Fn.new { |g| (np*g + x/g.pow(np))/n }
var g1 = x
var g2 = iter.call(g1)
while (g1 != g2) {
g1 = iter.call(g1)
g2 = iter.call(iter.call(g2))
}
return g1
}
var trios = [ [1728, 3, 2], [1024, 10, 1], [2, 2, 5] ]
for (trio in trios) {
System.print("%(trio[0]) ^ 1/%(trio[1])%(" "*trio[2]) = %(nthRoot.call(trio[0], trio[1]))")
}
- Output:
1728 ^ 1/3 = 12 1024 ^ 1/10 = 2 2 ^ 1/2 = 1.4142135623731
XBS
func nthRoot(x,a){
send x^(1/a);
}{a=2};
log(nthRoot(8,3));
- Output:
2
XPL0
include c:\cxpl\stdlib;
func real NRoot(A, N); \Return the Nth root of A
real A, N;
real X, X0, Y;
int I;
[X:= 1.0; \initial guess
repeat X0:= X;
Y:= 1.0;
for I:= 1 to fix(N)-1 do Y:= Y*X0;
X:= ((N-1.0)*X0 + A/Y) / N;
until abs(X-X0) < 1.0E-15; \(until X=X0 doesn't always work)
return X;
];
[Format(5, 15);
RlOut(0, NRoot( 2., 2.)); CrLf(0);
RlOut(0, Power( 2., 0.5)); CrLf(0); \for comparison
RlOut(0, NRoot(27., 3.)); CrLf(0);
RlOut(0, NRoot(1024.,10.)); CrLf(0);
]
Output:
1.414213562373100 1.414213562373100 3.000000000000000 2.000000000000000
zkl
fcn nthroot(nth,a,precision=1.0e-5){
x:=prev:=a=a.toFloat(); n1:=nth-1;
do{
prev=x;
x=( prev*n1 + a/prev.pow(n1) ) / nth;
}
while( not prev.closeTo(x,precision) );
x
}
nthroot(5,34) : "%.20f".fmt(_).println() # => 2.02439745849988828041
- Programming Tasks
- Classic CS problems and programs
- Simple
- 11l
- 360 Assembly
- AArch64 Assembly
- Action!
- Action! Tool Kit
- Action! Real Math
- Ada
- ALGOL 68
- ALGOL W
- ARM Assembly
- Arturo
- AutoHotkey
- AutoIt
- AWK
- BASIC
- Basic09
- BASIC256
- BBC BASIC
- Chipmunk Basic
- Craft Basic
- FreeBASIC
- FutureBasic
- Liberty BASIC
- PureBasic
- Run BASIC
- S-BASIC
- True BASIC
- Yabasic
- VBA
- Bc
- BQN
- Bracmat
- C
- C sharp
- C++
- Clojure
- COBOL
- CoffeeScript
- Common Lisp
- D
- Dart
- Delphi
- E
- EasyLang
- Elixir
- Erlang
- Excel
- F Sharp
- Factor
- Forth
- Fortran
- Go
- Groovy
- Haskell
- HicEst
- Icon
- Unicon
- J
- Java
- JavaScript
- Jq
- Julia
- Kotlin
- Lambdatalk
- Langur
- Lingo
- Logo
- Lua
- M2000 Interpreter
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Maxima
- Metafont
- МК-61/52
- NetRexx
- NewLISP
- Nim
- Nu
- Objeck
- OCaml
- Octave
- Oforth
- Oz
- PARI/GP
- Pascal
- Perl
- Phix
- Phixmonti
- PHP
- Picat
- PicoLisp
- PL/I
- PowerShell
- Prolog
- Python
- R
- Racket
- Raku
- RATFOR
- REXX
- Ring
- RPL
- Ruby
- Rust
- Sather
- Scala
- Scheme
- Seed7
- Sidef
- Smalltalk
- SPL
- Swift
- Tcl
- Ursala
- V (Vlang)
- Wren
- XBS
- XPL0
- Zkl
- M4/Omit