# PHP Science Programming

### Site Tools

nth_root_of_x

Back to: Arbitrary-Precision Math

## Nth Root of X

Sometimes we may want to compute a square root or a cube root or a fifth root some other root of a number to some specified degree of precision. The function below will compute the arbitrary-precision Nth root of argument X. As with all BC math functions, the X argument should be given as a numerical string, between quotes, like "1.2345" or '1.2345', so as not to be misinterpreted as a standard double-precision floating point value.

```A general-purpose, arbitrary-precision, Nth root computation
function based on a simple iterative algorithm.

Let:
X = Arbitrary-precision argument for which we seek the Nth root
N = Root to iterate (2=Square root, 3=Cube root, 4=4th root, ...)
a = Current approximation to Nth root of X
b = Next generation approximation derived from (a)
d = Decimals precision limit

================
Given (N, X, a):

Let:
n = N-1

START:
b = (a + X/(a^n)) / N

If (a == b) to (d) decimals, then finished, (b) is the root value.

If not, then at least one more approximation cycle is needed.
For next approximation, let current output (b) become next input (a):
a = b

Each successive value of (b) will be closer to the root than the
previous value.```

The root computing function is listed below.

```/*
------------------------------------------------------------------
This function computes the arbitrary-precision Nth root of a given
numerical string X, rounded to any specified number of decimals.

ARGUMENTS:
N = Root = Integer 2, 3, 4, ..., etc.
X = Numerical argument string for which we seek the Nth root

NumDecimals = Number of decimals at which to round off the result
if exact resolution is not possible.
ERRORS:
NO special error checking is done.
------------------------------------------------------------------
*/

function bcNth_Root_Of_X (\$N, \$X, \$NumDecimals=16)
{
\$a = sprintf("%1.16f", pow(\$X, 1/\$N)); // Compute first approximation
\$n = \$N - 1;
\$d = \$NumDecimals;
\$D = \$d + 8; // Add 8 extra decimals precision as rounding fuzz buffer

// Initialize iteration control loop.  The limit is set to 100 to prevent
// an infinite loop lockup, which would hang the function.  This limit
// should be far more than sufficient and never likely to be reached.
for (\$i=1;  \$i <= 100;   \$i++)
{
// Compute next generation approximation to Nth root of X from current (a).

// If (a == b) to desired precision, then done, (b) is root.
// Else current (b) becomes the new (a) for the next cycle.
if (bccomp(\$a,\$b,\$D) == 0) {break;} else {\$a = \$b;}
}
// Round off root to (d) decimals, then trim redundant zeros and/or decimal.
return rtrim(rtrim(bcadd(\$b, "0." . str_repeat(0,\$d) . "5", \$d), "0"), ".");
}```

Below is a program demonstrating the function followed by the full PHP source code.

```Given:
N = 12 = Root
X = '1194489593594883772'
Decimals = 31

Y = 12/Root of X  rounded to 31 decimals =
32.0945923761354614843241024968323

Orig X = 1194489593594883772
Check X = 1194489593594883771.9999999999999880163841257050607
Y = 32.0945923761354614843241024968323
Error = -0.0000000000000119836158742949393
```

```<?php

// Generate random example values.

\$N = mt_rand(2, 20);
\$X = bcmul(mt_rand(), mt_rand());
\$decimals = mt_rand(10, 112);

\$Y = bcNth_Root_Of_X(\$N, \$X, \$decimals);

\$CheckX = bcPoW(\$Y, \$N, \$decimals);
\$CheckXminusX = bcsub(\$CheckX, \$X, \$decimals);

print
"<pre>
Given:
N = \$N = Root
X = &#39;\$X&#39;
Decimals = \$decimals

Y = \$N/Root of X  rounded to \$decimals decimals =
\$Y

Orig X = \$X
Check X = \$CheckX
Y = \$Y
Error = \$CheckXminusX
</pre>";

function bcNth_Root_of_X (\$N, \$X, \$NumDecimals=16)
{
\$a = sprintf("%1.16f", pow(\$X, 1/\$N)); // Compute first approximation
\$n = \$N - 1;
\$d = \$NumDecimals;
\$D = \$d + 8;

for (\$i=1;  \$i <= 100;   \$i++)
{ 