Exponential problems and their C representation - c

I came across well-known N-Queen problem and I was wondering how to write a program to calculate number of possibilities in this particular problem. My program can find solution fast for really small N's (since it's heuristic).
I'd also like to know how to represent such big numbers in C. Are there any algorithms for really big numbers? Anytime I write and implementation of my own arithmetic I get i. e. quadratic multiplication with tons of memory allocation what cannot be fast. Thank you in advance for exhaustive answer.

here is a nice solution, using recursion
(taken from: <http://rosettacode.org/wiki/N-queens_problem#C>)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint32_t uint;
uint full, *qs, count = 0, nn;
void solve(uint d, uint c, uint l, uint r)
{
uint b, a, *s;
if (!d) // exit condition
{
count++;
#if 0
printf("\nNo. %d\n===========\n", count);
for (a = 0; a < nn; a++, putchar('\n'))
{
for (b = 0; b < nn; b++, putchar(' '))
{
putchar(" -QQ"[((b == qs[a])<<1)|((a + b)&1)]);
} // end for
} // end for
#endif
return;
} // end if
a = (c | (l <<= 1) | (r >>= 1)) & full;
if (a != full)
{
for (*(s = qs + --d) = 0, b = 1; b <= full; (*s)++, b <<= 1)
{
if (!(b & a))
{
solve(d, b|c, b|l, b|r);
} // end if
} // end for
} // end if
} // end function: solve
int main(int n, char **argv)
{
if (n <= 1 || (nn = atoi(argv[1])) <= 0) nn = 8;
qs = calloc(nn, sizeof(int));
full = (1U << nn) - 1;
solve(nn, 0, 0, 0);
printf("\nSolutions: %d\n", count);
return 0;
} // end function: main

Related

How to speed up printf in C

I have a task to print all the prime numbers between 1 and 1000000 in class and the fastest 10 programs get extra marks. The main problem is the time it takes for the prime numbers to be printed to the console.
Basically using the Sieve of Eratosthenes I produce an array with only boolean values in it. The boolean value Numbers[i] is true if i+2 is a prime number.
for(i = 0; i <= n - 2; ++i)
if (Numbers[i]) // True if the number is prime
printf("%d\n", i+2);
Printf seems to be really slow as the program can generate the list of primes in about 0.035 s but then takes a further 11 seconds to print the list. Is there anyway I can speed this up, thanks.
Beneath is a slightly unoptimized implementation (although I skipped the intermediate list and print directly) of what I think you were supposed to do. Running that program on an AMD A8-6600K with a small load (mainly a Youtube music-video for some personal entertainment) results in
real 0m1.211s
user 0m0.047s
sys 0m0.122s
averaged over a couple of runs. So the problem lies in your implementation of the sieve or you are hiding some essential facts about your hardware.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <limits.h>
#include <string.h>
/* I call it a general bitset. Others might call it an abomination. YMMV. */
# define ERAT_BITS (sizeof(uint32_t)*CHAR_BIT)
# define GET_BIT(s,n) ((*(s+(n/ERAT_BITS)) & ( 1<<( n % ERAT_BITS ))) != 0)
# define SET_BIT(s,n) (*(s+(n/ERAT_BITS)) |= ( 1<<( n % ERAT_BITS )))
# define CLEAR_BIT(s,n) (*(s+(n/ERAT_BITS)) &= ~( 1<<( n % ERAT_BITS )))
# define TOG_BIT(s,n) (*(s+(n/ERAT_BITS)) ^= ( 1<<( n % ERAT_BITS )))
/* size is the size in bits, the overall size might be bigger */
typedef struct mp_bitset_t {
uint32_t size;
uint32_t *content;
} mp_bitset_t;
# define mp_bitset_alloc(bst, n) \
do {\
(bst)->content=malloc(( n /(sizeof(uint32_t)) + 1 ));\
if ((bst)->content == NULL) {\
fprintf(stderr, "memory allocation for bitset failed");\
exit(EXIT_FAILURE);\
}\
(bst)->size = n;\
} while (0)
# define mp_bitset_size(bst) ((bst)->size)
# define mp_bitset_setall(bst) memset((bst)->content,~(uint32_t)(0),\
(bst->size /(sizeof(uint32_t) ) +1 ))
# define mp_bitset_clearall(bst) memset((bst)->content,0,\
(bst->size /(sizeof(uint32_t) ) +1 ))
# define mp_bitset_clear(bst,n) CLEAR_BIT((bst)->content, n)
# define mp_bitset_set(bst,n) SET_BIT((bst)->content, n)
# define mp_bitset_get(bst,n) GET_BIT((bst)->content, n)
# define mp_bitset_free(bst) \
do {\
free((bst)->content);\
free(bst);\
} while (0)
uint32_t mp_bitset_nextset(mp_bitset_t * bst, uint32_t n);
uint32_t mp_bitset_prevset(mp_bitset_t * bst, uint32_t n);
void mp_eratosthenes(mp_bitset_t * bst);
/* It's called Hallek's method but it has many inventors*/
static uint32_t isqrt(uint32_t n)
{
uint32_t s, rem, root;
if (n < 1)
return 0;
/* This is actually the highest square but it goes
* downward from this, quite fast */
s = 1 << 30;
rem = n;
root = 0;
while (s > 0) {
if (rem >= (s | root)) {
rem -= (s | root);
root >>= 1;
root |= s;
} else {
root >>= 1;
}
s >>= 2;
}
return root;
}
uint32_t mp_bitset_nextset(mp_bitset_t *bst, uint32_t n)
{
while ((n < mp_bitset_size(bst)) && (!mp_bitset_get(bst, n))) {
n++;
}
return n;
}
/*
* Standard method, quite antique now, but good enough for the handful
* of primes needed here.
*/
void mp_eratosthenes(mp_bitset_t *bst)
{
uint32_t n, k, r, j;
mp_bitset_setall(bst);
mp_bitset_clear(bst, 0);
mp_bitset_clear(bst, 1);
n = mp_bitset_size(bst);
r = isqrt(n);
for (k = 4; k < n; k += 2)
mp_bitset_clear(bst, k);
k = 0;
while ((k = mp_bitset_nextset(bst, k + 1)) < n) {
if (k > r) {
break;
}
for (j = k * k; j < n; j += k * 2) {
mp_bitset_clear(bst, j);
}
}
}
#define UPPER_LIMIT 1000000 /* one million */
int main(void) {
mp_bitset_t *bst;
uint32_t n, k, j;
bst = malloc(sizeof(mp_bitset_t));
if(bst == NULL) {
fprintf(stderr, "failed to allocate %zu bytes\n",sizeof(mp_bitset_t));
exit(EXIT_FAILURE);
}
mp_bitset_alloc(bst, UPPER_LIMIT);
mp_bitset_setall(bst);
mp_bitset_clear(bst, 0); // 0 is not prime b.d.
mp_bitset_clear(bst, 1); // 1 is not prime b.d.
n = mp_bitset_size(bst);
for (k = 4; k < n; k += 2) {
mp_bitset_clear(bst, k);
}
k = 0;
while ((k = mp_bitset_nextset(bst, k + 1)) < n) {
printf("%" PRIu32 "\n", k);
for (j = k * k; j < n; j += k * 2) {
mp_bitset_clear(bst, j);
}
}
mp_bitset_free(bst);
return EXIT_SUCCESS;
}
Compiled with
gcc-4.9 -O3 -g3 -W -Wall -Wextra -Wuninitialized -Wstrict-aliasing -pedantic -std=c11 tests.c -o tests
(GCC is gcc-4.9.real (Ubuntu 4.9.4-2ubuntu1~14.04.1) 4.9.4)
Since by default console output is line buffered, which is the reason of the increased time.
You can use the setvbuf function to allow printing to console/stdout only in chunks rather than for each iteration.
E.g.
char buffer[256];
setvbuf(stdout, buffer, _IOFBF, sizeof(buffer));
You can alter the size of buffer according to your needs.
IOFBF option is for full buffering i.e. output will be printed once the buffer is full.
See setvbuf for more details

Not Getting a Calculated Value of the Constant e

Not really sure what the problem is here. I know I have the factorial function correct because I tested it separately. But the function that calculates e is tripping me up. All I have to do is add all the values after each factorial has been calculated. But I am having trouble translating that into C code. The problem for sure is in my second function. Any help or pointers would be appreciated.
#include <stdio.h>
#include <math.h>
#define NOERROR 0
#define DECIMAL_PLACES 16
#define EXPECTED_E 2.7182818284590452L
long calcFactorial(int);
double calcE(int);
long calcFactorial(int n)
{
long sum = 0;
sum = n;
if(n == 0)
{
return 1;
}
else
{
while(n != 1)
{
sum = sum * (n - 1);
n = n - 1;
}
printf("factorial sum: %ld\n", sum);
return sum;
}
}
double calcE(int n)
{
double e = 0;
int counter = 0;
for (counter = 0; counter < DECIMAL_PLACES; counter++)
{
e = e + (1/calcFactorial(n));
n--;
}
printf("Expected e value: %0.16Lf\n", EXPECTED_E);
printf("Calculated e value: %0.16d\n", e);
return e;
}
int main()
{
calcE(10);
}
You have a lot of errors in your code:
using long to store floating point result. Use double
passing n but looping using a bigger value: n becomes negative after a while: infinite loop
e = e + (1/calcFactorial(counter)); adds 0 to e most of the time because calcFactorial returns an integer (long)
EXPECTED_E constant had L suffix, which means long. Not what you want.
Fixed version:
#include <stdio.h>
#include <math.h>
#define NOERROR 0
#define DECIMAL_PLACES 16
#define EXPECTED_E 2.7182818284590452
long calcFactorial(int);
void calcE(int);
long calcFactorial(int n)
{
long sum = 0;
sum = n;
if(n == 0)
{
return 1;
}
else
{
while(n != 1)
{
sum *= (n - 1);
n = n - 1;
}
return sum;
}
}
void calcE(int n)
{
double e = 0;
int counter = 0;
for (counter = 0; counter < n; counter++)
{
e = e + (1.0/calcFactorial(counter));
}
printf("Expected e value: %0.16lf\n", EXPECTED_E);
printf("Calculated e value: %0.16lf\n", e);
}
int main( )
{
calcE(10);
}
This code outputs:
Expected e value: 2.7182818284590451
Calculated e value: 2.7182815255731922
Note: you are limited to a given maximum for n because after that you'll overflow long. Maybe consider using long long or unsigned long long for the factorial part (and even with that you're severely limited).
Jean-François Fabre highlighted your formal errors quite well, but it is not so far fetched to calculate with integers up to the final division--which must be done with floats, of course. The trick can be done with a method called binary splitting and, to my own surprise, it works very well native doubles, only one decimal digit off. It is also very simple to implement (code below written with legibility in mind).
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define BS_AFU 0
#define BS_AOK 1
static int exp1_bin_split(uint64_t a, uint64_t b, uint64_t *P, uint64_t *Q){
int err = BS_AOK;
uint64_t p1, q1, p2, q2, t1, one;
one = 1UL;
t1 = b - a;
if(t1 == one){
*P = one;
*Q = b;
return err;
}
t1 = (a + b) >> 1;
err = exp1_bin_split(a, t1, &p1, &q1);
if(err != BS_AOK){
return err;
}
err = exp1_bin_split(t1, b, &p2, &q2);
if(err != BS_AOK){
return err;
}
*P = q2 * p1 + p2;
*Q = q1 * q2;
return err;
}
#include <float.h>
static int exp1(double *a){
int err = BS_AOK;
uint64_t p = 0UL, q = 0UL, zero = 0UL;
double dp, dq;
// DBL_DIG + 2 = 17 here on my machine
// had DBL_DIG + 1 first but found out via T&E that
// one more is still inside the precision of a binary64
err = exp1_bin_split(zero, DBL_DIG + 2, &p, &q);
if(err != BS_AOK){
return err;
}
p = p + q;
dp = (double) p;
dq = (double) q;
*a = dp/dq;
return err;
}
int main(void){
double e = 0.0;
int err = BS_AOK;
err = exp1(&e);
if(err != BS_AOK){
fprintf(stderr,"Something went wrong in computing e\n");
exit(EXIT_FAILURE);
}
printf("exp(1) ~ 2.7182818284590452353602874713526624978\nexp1 ~ %.20g\n",e);
exit(EXIT_SUCCESS);
}
It uses the same algorithm as you do but does not compute the individual fractions and sums them up as floats but does it all at once with integers such that we have a large fraction at the end to resemble the approximation of exp(1). That explanation is a bit over-simplified, please read the linked paper for the details.

Instead of printing the binary number out how would I store it as a variable?

I pass in a hex number into hex2bin and it prints out the binary number correctly but I don't want it to print out the number I want to return the number so I can use it to find the cardinality of the number. How would I store the number instead of printing it out?
int hex2bin (int n){
int i,k,mask;
for(i = sizeof(int) * 8 - 1; i >= 0; i--){
mask = 1 << i;
k = n & mask;
k == 0 ? printf("0"):printf("1");
}
return 0;
}
Perhaps something like this?
int result = 0;
int i, k...
...
result = result | (((k == 0) ? 0 : 1) << i;
...
return result;
Instead of being clever with an int, you could of course also simply use an array of variables instead.
Store the number in a string whose space is provided by a compound literal (Available since C99).
It works like OP's flow: Loop up to sizeof(int) * 8 times, finding the value of 1 bit and print/save it.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
// Maximum buffer size needed
#define UTOA_BASE_2 (sizeof(unsigned)*CHAR_BIT + 1)
char *utoa_base2(char *s, unsigned x) {
s += UTOA_BASE_2 - 1;
*s = '\0';
do {
*(--s) = "01"[x % 2];
x /= 2;
} while (x);
return s;
}
#define TO_BASE2(x) utoa_base2((char [UTOA_BASE_2]){0} , (x))
void test(unsigned x) {
printf("base10:%10u base2:%5s ", x, TO_BASE2(x));
char *s = TO_BASE2(x);
// do stuff with `s`, it is valid for until the end of this block
printf("%s\n", s);
}
int main(void) {
test(0);
test(25);
test(UINT_MAX);
}
Sample output
base10: 0 base2: 0 0
base10: 25 base2:11001 11001
base10:4294967295 base2:11111111111111111111111111111111 11111111111111111111111111111111
This is a variation of this base-n answer.
You can use the strcat function to do that.
Note that the new hex2bin function in this answer assumes that the parameter char *buf has already been allocated and can hold at least 1+sizeof(int)*8 bytes including the null terminator:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// assume: buf is at least length 33
int hex2bin (int n, char *buf)
{
int i,k,mask;
for(i = sizeof(int) * 8 - 1; i >= 0; i--){
mask = 1 << i;
k = n & mask;
k == 0 ? strcat(buf, "0") : strcat(buf, "1");
}
return 0;
}
int main()
{
int n = 66555;
char buffer[1+sizeof(int)*8] = { 0 } ;
hex2bin(n, buffer);
printf("%s\n", buffer);
return 0;
}
I hope you will find this helpful :)
bool convertDecimalBNR(INT32 nDecimalValue, UINT32 * punFieldValue, INT32 nBitCount, DecimalBNRType * pDecimalSpecification)
{
bool bBNRConverted = false;
INT32 nBitIndex = nBitCount - 1;
INT32 nBitValue = anTwoExponents[nBitIndex];
*punFieldValue = 0;
if ((nDecimalValue >= pDecimalSpecification->nMinValue) && (nDecimalValue <= pDecimalSpecification->nMaxValue))
{
// if the value is negative, then add (-1 * (2 ^ (nBitCount - 1))) on itself and go on just like a positive value calculation.
if (nDecimalValue < 0)
{
nDecimalValue += nBitValue;
nBitIndex--;
nBitValue /= 2;
*punFieldValue |= BIT_0_ONLY_ONE;
}
while (nBitIndex >= 0)
{
*punFieldValue = (*punFieldValue << 1);
if (nDecimalValue >= nBitValue)
{
nDecimalValue -= nBitValue;
*punFieldValue |= BIT_0_ONLY_ONE;
}
nBitIndex--;
nBitValue /= 2;
}
if (nDecimalValue <= nBitValue)
{
bBNRConverted = true;
}
}
return (bBNRConverted);
}

Optimizing a program for solving ax+by=c with positve integers

I am writing a program that for any given positive integers a < b < c will output YES if there is a solution to ax+by=c where x and y are also positive integers (x,y > 0), or NO if there isn't a solution. Keep in mind that I need to work with big numbers.
The approach I take for solving this problem is that I subtract b from c and I check if this number is divisable by a.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
int main(){
unsigned long long int a, b, c;
scanf("%I64u %I64u %I64u", &a, &b, &c);
while(c>=a+b){ //if c becomes less than a+b, than there's no sollution
c-=b;
if(c%a==0){
printf("YES");
return 0;
}
}
printf("NO");
return 0;
}
is there a more optimised way to find wether ax+by=c has positive sollutions? I tried reading about linear Diophantine equations, but all I found is a way to find integer sollutions (but not positive).
My approach so far.
Use Euclidean Algorithm to find GCD(a, b)
There are solutions (in integers) to ax + by = c if and only if GCD(a, b) divides c. No integer solutions means no positive solutions.
use Extended Euclidean Algorithm to solve the Diophantine equation and return NO if it gives non-positive solutions.
For comparisons it's hard to find examples that take longer than a second but in deciding on thousands of random equations the performance difference is noticeable. This Lecture has a solution for finding the number of positive
solutions to a Linear Diophantine Equation.
typedef unsigned long long int BigInt;
int pos_solvable(BigInt a, BigInt b, BigInt c) {
/* returns 1 if there exists x, y > 0 s.t. ax + by = c
* where 0 < a < b < c
* returns 0, otherwise
*/
BigInt gcd = a, bb = b, temp;
while (bb) { /* Euclidean Algorithm */
temp = bb;
bb = gcd % bb;
gcd = temp;
}
if (c % gcd) { /* no integer (or positive) solution */
return 0;
} else {
/* Extended Euclidean Algorithm */
BigInt s = 0, old_s = 1;
BigInt t = 1, old_t = 0;
BigInt r = b / gcd, old_r = a / gcd;
while (r > 0) {
BigInt quotient = old_r / r;
BigInt ds = quotient * s;
BigInt dt = quotient * t;
if (ds > old_s || dt > old_t)
return 0; /* will give non-positive solution */
temp = s;
s = old_s - ds;
old_s = temp;
temp = t;
t = old_t - dt;
old_t = temp;
temp = r;
r = old_r - quotient * r;
old_r = temp;
}
return 1;
}
}
The following is a comment but too big for the comment section.
This is posted to help others dig into this problem a little deeper.
OP: Incorporate any of in your post if you like.
What is still needed are some challenging a,b,c.
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//#define LLF "%I64u"
#define LLF "%llu"
int main(void) {
unsigned long long int a, b, c, x, y, sum, c0;
// scanf(LLF LLF LLF, &a, &b, &c);
c = c0 = ULLONG_MAX;
b = 10000223;
a = 10000169;
y = 0;
sum = a + b;
time_t t0 = time(NULL);
while (c >= sum) { //if c becomes less than a+b, than there's no solution
c -= b;
if (c % a == 0) {
break;
}
}
if (c % a == 0) {
y = (c0 - c) / b;
x = c / a;
printf("YES " LLF "*" LLF " + " LLF "*" LLF " = " LLF "\n", a, x, b, y, c);
} else {
printf("NO\n");
}
time_t t1 = time(NULL);
printf("time :" LLF "\n", (unsigned long long) (t1 - t0));
return 0;
}
Output
YES 10000169*1844638544065 + 10000223*4688810 = 18446697184563946985
time :0

Algorithm to find nth root of a number

I am looking for an efficient algorithm to find nth root of a number. The answer must be an integer. I have found that newtons method and bisection method are popular methods. Are there any efficient and simple methods for integer output?
#include <math.h>
inline int root(int input, int n)
{
return round(pow(input, 1./n));
}
This works for pretty much the whole integer range (as IEEE754 8-byte doubles can represent the whole 32-bit int range exactly, which are the representations and sizes that are used on pretty much every system). And I doubt any integer based algorithm is faster on non-ancient hardware. Including ARM. Embedded controllers (the microwave washing machine kind) might not have floating point hardware though. But that part of the question was underspecified.
I know this thread is probably dead, but I don't see any answers I like and that bugs me...
int root(int a, int n) {
int v = 1, bit, tp, t;
if (n == 0) return 0; //error: zeroth root is indeterminate!
if (n == 1) return a;
tp = iPow(v,n);
while (tp < a) { // first power of two such that v**n >= a
v <<= 1;
tp = iPow(v,n);
}
if (tp == a) return v; // answer is a power of two
v >>= 1;
bit = v >> 1;
tp = iPow(v, n); // v is highest power of two such that v**n < a
while (a > tp) {
v += bit; // add bit to value
t = iPow(v, n);
if (t > a) v -= bit; // did we add too much?
else tp = t;
if ( (bit >>= 1) == 0) break;
}
return v; // closest integer such that v**n <= a
}
// used by root function...
int iPow(int a, int e) {
int r = 1;
if (e == 0) return r;
while (e != 0) {
if ((e & 1) == 1) r *= a;
e >>= 1;
a *= a;
}
return r;
}
This method will also work with arbitrary precision fixed point math in case you want to compute something like sqrt(2) to 100 decimal places...
I question your use of "algorithm" when speaking of C programs. Programs and algorithms are not the same (an algorithm is mathematical; a C program is expected to be implementing some algorithm).
But on current processors (like in recent x86-64 laptops or desktops) the FPU is doing fairly well. I guess (but did not benchmark) that a fast way of computing the n-th root could be,
inline unsigned root(unsigned x, unsigned n) {
switch (n) {
case 0: return 1;
case 1: return x;
case 2: return (unsigned)sqrt((double)x);
case 3: return (unsigned)cbrt((double)x);
default: return (unsigned) pow (x, 1.0/n);
}
}
(I made a switch because many processors have hardware to compute sqrt and some have hardware to compute cbrt ..., so you should prefer these when relevant...).
I am not sure that n-th root of a negative number makes sense in general. So my root function takes some unsigned x and returns some unsigned number.  
Here is an efficient general implementation in C, using a simplified version of the "shifting nth root algorithm" to compute the floor of the nth root of x:
uint64_t iroot(const uint64_t x, const unsigned n)
{
if ((x == 0) || (n == 0)) return 0;
if (n == 1) return x;
uint64_t r = 1;
for (int s = ((ilog2(x) / n) * n) - n; s >= 0; s -= n)
{
r <<= 1;
r |= (ipow(r|1, n) <= (x >> s));
}
return r;
}
It needs this function to compute the nth power of x (using the method of exponentiation by squaring):
uint64_t ipow(uint64_t x, unsigned n)
{
if (x <= 1) return x;
uint64_t y = 1;
for (; n != 0; n >>= 1, x *= x)
if (n & 1)
y *= x;
return y;
}
and this function to compute the floor of base-2 logarithm of x:
int ilog2(uint64_t x)
{
#if __has_builtin(__builtin_clzll)
return 63 - ((x != 0) * (int)__builtin_clzll(x)) - ((x == 0) * 64);
#else
int y = -(x == 0);
for (unsigned k = 64 / 2; k != 0; k /= 2)
if ((x >> k) != 0)
{ x >>= k; y += k; }
return y;
#endif
}
Note: This assumes that your compiler understands GCC's __has_builtin test and that your compiler's uint64_t type is the same size as an unsigned long long.
You can try this C function to get the nth_root of an unsigned integer :
unsigned initial_guess_nth_root(unsigned n, unsigned nth){
unsigned res = 1;
for(; n >>= 1; ++res);
return nth ? 1 << (res + nth - 1) / nth : 0 ;
}
// return a number that, when multiplied by itself nth times, makes N.
unsigned nth_root(const unsigned n, const unsigned nth) {
unsigned a = initial_guess_nth_root(n , nth), b, c, r = nth ? a + (n > 0) : n == 1 ;
for (; a < r; b = a + (nth - 1) * r, a = b / nth)
for (r = a, a = n, c = nth - 1; c && (a /= r); --c);
return r;
}
Example of output :
24 == (int) pow(15625, 1.0/3)
25 == nth_root(15625, 3)
0 == nth_root(0, 0)
1 == nth_root(1, 0)
4 == nth_root(4096, 6)
13 == nth_root(18446744073709551614, 17) // 64-bit 20 digits
11 == nth_root(340282366920938463463374607431768211454, 37) // 128-bit 39 digits
Here is the github source.

Resources