views:

218

answers:

4

Is there a C++ library that can take nth roots of big numbers (numbers than can't fit in an unsigned long long)?

+8  A: 

You can use GMP, a popular open source arbitrary-precision math library. It has C++ bindings.

Matthew Flaschen
Yep, in particular the function mpz_root.
GregS
+2  A: 

If you want to code this yourself, check out the Wikipedia page on nth roots:

http://en.wikipedia.org/wiki/Nth_root

The iterative algorithm is quite simple:

The nth root of a number A can be computed by the nth root algorithm, a special case of Newton's method. Start with an initial guess x(0) and then iterate using the recurrence relation

x(k+1) = [(n - 1) * x(k) + A / x(k)^(n - 1)] / n

Stop once you've converged to the desired accuracy.

garamfalvi
+1  A: 

It depends how much bigger than 2^64 you want to go, I guess. Just using doubles is good to about 1 part in 10^9. I wrote a test program in C:

#include <stdio.h>
#include <math.h>

int main(int argc, char **argv)
{
    unsigned long long x;
    double dx;
    int i;

    //make x the max possible value
    x = ~0ULL;
    dx = (double)x;
    printf("Starting with dx = %f\n", dx);
    //print the 2th to 20th roots
    for (i = 2; i < 21; i++)
    {
        printf("%dth root %.15f\n", i, pow(dx, 1.0/i));
    }
    return 0;
}

which produced the following output:

Starting with dx = 18446744073709551616.000000
2th root 4294967296.000000000000000
3th root 2642245.949629130773246
4th root 65536.000000000000000
5th root 7131.550214521852467
6th root 1625.498677215435691
7th root 565.293831000991759
8th root 256.000000000000000
9th root 138.247646578215154
10th root 84.448506289465257
11th root 56.421840319745364
12th root 40.317473596635935
13th root 30.338480458853493
14th root 23.775908626191171
15th root 19.248400577313866
16th root 16.000000000000000
17th root 13.592188707483222
18th root 11.757875938204789
19th root 10.327513583579238
20th root 9.189586839976281

Then I compared with Wolfram Alpha for each root to get the error I quoted above.

Depending on your application, perhaps this will be good enough.

mtrw
Note that the standard way to set all bits is the `~` operator, i.e. `x = ~0ULL`
MSalters
@MSalters - my face, it is red. Thanks.
mtrw
+1  A: 

Try also MAPM and qd.

MAPM is written in C but also has a C++ API. qd is written in C++ but also has a C API.

lhf