Just a quick issue I have in c. In this case x is always 10, and n varies. the function works fine when n < 11, but as soon as it goes above 11 the function churns out random values which are sometimes negative too. Any tips?
int myPow(int x,int n)
{
int i; /* Variable used in loop counter */
long number = 1;
for (i = 0; i < n; i++)
number *= x;
return(number);
}
Typically code like this is undefined behavior due to int overflow.
Yet OP is using long in the multiplication, so it is UB once the product exceeds LONG_MAX.
When INT_MAX and LONG_MAX are 2,147,483,647 (231 - 1), codes suffers UB with my_pow(10,10).
When LONG_MAX in 9,223,372,036,854,775,807 (263 - 1), codes suffers UB with my_pow(10,19) and my_pow(10,10) is implementation defined behavior converting the large long to int on the return.
Code using wider intergern types to cope with larger values, but integer math is only good for so far with an exponential function
Some dusty old sample code the considers all int values and uses Exponentiation by squaring with projection against signed integer overflow.
#define DIV0 INTMAX_MIN
// Likely needs work ...
static bool safe_mul(intmax_t a, intmax_t b, intmax_t *product) {
if (a > 0) {
if (b > 0) {
if (a > INTMAX_MAX / b)
return true; // a positive, b positive
} else if (b < INTMAX_MIN / a)
return true; // a positive, b not positive
} else if (b > 0) {
if (a < INTMAX_MIN / b)
return true; // a not positive, b positive
} else if (a != 0 && b < INTMAX_MAX / a)
return true; // a not positive, b not positive
*product = a * b;
return false;
}
intmax_t pow_i(int base, int expo) {
if (expo < 0) {
if (base == 1)
return 1;
if (base == -1)
return (expo % 2) ? -1 : 1;
if (base == 0)
return DIV0; //
return 0; // round toward 0
}
intmax_t wide_base = base;
intmax_t pow = 1;
while (expo > 0) {
if (expo % 2) {
if (safe_mul(pow, wide_base, &pow))
return 0;
}
if (safe_mul(wide_base, wide_base, &wide_base))
return 0;
expo /= 2;
}
return pow;
}
Related
Problem statement :
Given a 32-bit signed integer, reverse digits of an integer.
Note: Assume we are dealing with an environment that could only store
integers within the 32-bit signed integer range: [ −2^31, 2^31 − 1]. For
the purpose of this problem, assume that your function returns 0 when
the reversed integer overflows.
I'm trying to implement the recursive function reverseRec(), It's working for smaller values but it's a mess for the edge cases.
int reverseRec(int x)
{
if(abs(x)<=9)
{
return x;
}
else
{
return reverseRec(x/10) + ((x%10)*(pow(10, (floor(log10(abs(x)))))));
}
}
I've implemented non recursive function which is working just fine :
int reverse(int x)
{
long long val = 0;
do{
val = val*10 + (x%10);
x /= 10;
}while(x);
return (val < INT_MIN || val > INT_MAX) ? 0 : val;
}
Here I use variable val of long long type to check the result with MAX and MIN of signed int type but the description of the problem specifically mentioned that we need to deal within the range of 32-bit integer, although somehow it got accepted but I'm just curious If there is a way to implement a recursive function using only int datatype ?
One more thing even if I consider using long long I'm failing to implement it in the recursive function reverseRec().
If there is a way to implement a recursive function using only int datatype ?
(and) returns 0 when the reversed integer overflows
Yes.
For such +/- problems, I like to fold the int values to one side and negate as needed. The folding to one side (- or +) simplifies overflow detection as only a single side needs testing
I prefer folding to the negative side as there are more negatives, than positives. (With 32-bit int, really didn't make any difference for this problem.)
As code forms the reversed value, test if the following r * 10 + least_digit may overflow before doing it.
An int only recursive solution to reverse an int. Overflow returns 0.
#include <limits.h>
#include <stdio.h>
static int reverse_recurse(int i, int r) {
if (i) {
int least_digit = i % 10;
if (r <= INT_MIN / 10 && (r < INT_MIN / 10 || least_digit < INT_MIN % 10)) {
return 1; /// Overflow indication
}
r = reverse_recurse(i / 10, r * 10 + least_digit);
}
return r;
}
// Reverse an int, overflow returns 0
int reverse_int(int i) {
// Proceed with negative values, they have more range than + side
int r = reverse_recurse(i > 0 ? -i : i, 0);
if (r > 0) {
return 0;
}
if (i > 0) {
if (r < -INT_MAX) {
return 0;
}
r = -r;
}
return r;
}
Test
int main(void) {
int t[] = {0, 1, 42, 1234567890, 1234567892, INT_MAX, INT_MIN};
for (unsigned i = 0; i < sizeof t / sizeof t[0]; i++) {
printf("%11d %11d\n", t[i], reverse_int(t[i]));
if (t[i] != INT_MIN) {
printf("%11d %11d\n", -t[i], reverse_int(-t[i]));
}
}
}
Output
0 0
0 0
1 1
-1 -1
42 24
-42 -24
1234567890 987654321
-1234567890 -987654321
1234567892 0
-1234567892 0
2147483647 0
-2147483647 0
-2147483648 0
You could add a second parameter:
int reverseRec(int x, int reversed)
{
if(x == 0)
{
return reversed;
}
else
{
return reverseRec(x/10, reversed * 10 + x%10);
}
}
And call the function passing the 0 for the second parameter. If you want negative numbers you can check the sign before and pass the absolute value to this function.
In trying to learn C programming I programed this question and get some correct results and some incorrect. I don't see the reason for the difference.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h> // requires adding link to math -lm as in: gcc b.c -lm -o q11
int ReverseInt(int startValue, int decimalPlace)
{
if(decimalPlace == 0) // if done returns value
{
return startValue;
}
int temp = startValue % 10; // gets units digit
int newStart = (startValue -temp)/10; // computes new starting value after removing one digit
int newDecimal = decimalPlace -1;
int value = temp*pow(10,decimalPlace);
return value + ReverseInt(newStart,newDecimal); // calls itself recursively until done
}
int main()
{
int x, decimalP, startValue;
printf("Input number to be reversed \n Please note number must be less than 214748364 :");
scanf("%d", &x);
if (x > 214748364)
{
printf("Input number to be reversed \n Please note number must be less than 214748364 :");
scanf("%d", &x);
}
decimalP = round(log10(x)); // computes the number of powers of 10 - 0 being units etc.
startValue = ReverseInt(x, decimalP); // calls function with number to be reversed and powers of 10
printf("\n reverse of %d is %d \n", x, startValue);
}
Output is: reverse of 1234 is 4321 but then reverse of 4321 is 12340
It's late and nothing better does not come into my mind. No float calculations. Of course, integer has to be big enough to accommodate the result. Otherwise it is an UB.
int rev(int x, int partial, int *max)
{
int result;
if(x / partial < 10 && (int)(x / partial) > -10)
{
*max = partial;
return abs(x % 10) * partial;
}
result = rev(x, partial * 10, max) + abs(((x / (int)(*max / partial)) % 10) * partial);
return result;
}
int reverse(int x)
{
int max;
return rev(x, 1, &max) * ((x < 0) ? -1 : 1);
}
int main(void){
printf("%d", reverse(-456789));
}
https://godbolt.org/z/M1eezf
unsigned rev(unsigned x, unsigned partial, unsigned *max)
{
unsigned result;
if(x / partial < 10)
{
*max = partial;
return (x % 10) * partial;
}
result = rev(x, partial * 10, max) + (x / (*max / partial) % 10) * partial;
return result;
}
unsigned reverse(unsigned x)
{
unsigned max;
return rev(x, 1, &max);
}
int main(void){
printf("%u", reverse(123456));
}
when using long long to store the result all possible integers can be reversed
long long rev(int x, long long partial, long long *max)
{
long long result;
if(x / partial < 10 && (int)(x / partial) > -10)
{
*max = partial;
return abs(x % 10) * partial;
}
result = rev(x, partial * 10, max) + abs(((x / (int)(*max / partial)) % 10) * partial);
return result;
}
long long reverse(int x)
{
long long max;
return rev(x, 1, &max) * ((x < 0) ? -1 : 1);
}
int main(void){
printf("%d reversed %lld\n", INT_MIN, reverse(INT_MIN));
printf("%d reversed %lld\n", INT_MAX, reverse(INT_MAX));
}
https://godbolt.org/z/KMfbxz
I am assuming by reversing an integer you mean turning 129 to 921 or 120 to 21.
You need an initial method to initialize your recursive function.
Your recursive function must figure out how many decimal places your integer uses. This can be found by using log base 10 with the value and then converting the result to a integer.
log10 (103) approx. 2.04 => 2
Modulus the initial value by 10 to get the ones place and store it in a variable called temp
Subtract the ones place from the initial value and store that in a variable called newStart.
divide this value by 10
Subtract one from the decimal place and store in another variable called newDecimal.
Return the ones place times 10 to the power of the decimal place and add it to the function where the initial value is newStart and the decimalPlace is newDecimal.
#include <stdio.h>
#include <math.h>
int ReverseInt(int startValue, int decimalPlace);
int main()
{
int i = -54;
int positive = i < 0? i*-1 : i;
double d = log10(positive);
int output = ReverseInt(positive,(int)d);
int correctedOutput = i < 0? output*-1 : output;
printf("%d \n",correctedOutput);
return 0;
}
int ReverseInt(int startValue, int decimalPlace)
{
if(decimalPlace == 0)
{
return startValue;
}
int temp = startValue % 10;
int newStart = (startValue -temp)/10;
int newDecimal = decimalPlace -1;
int value = temp*pow(10,decimalPlace);
return value + ReverseInt(newStart,newDecimal);
}
I need to check if the result of a mathematical division is an integer or not.
For example, 8 / 2 = 4
is ok.
but 5 / 2 = 2.5
shouldn't be ok.
I've tried the following:
bool isPrime(int num)
{
/* Checks all the numbers before the given input. If the result of
dividing
the input by one of those numbers is an int, then the input is not a
prime number. */
int i, check;
double result;
for (i=2; i<num; i++) {
result = (double) num / i;
check = (int) result;
if (isdigit(check))
return false;
}
return true;
}
I'm having nightmares about isdigit and how to insert the parameter in the right way. I know it requires an int, but I have a double, so I can't really put those pieces together.
It seems like you're trying to do something like this:
result = (double) num / i;
check = (int) result;
if(check == result) {
...
Logically, this is correct. But it will not work in practice because floats does not have infinite precision.
The proper way to check divisibility is using the modulo operator:
if(num % i == 0) {
// Code to run if num / i is an integer
You want to test if an integer division has no remainder: use the modulo operator % that computes the remainder. The isdigit() function has a different purpose: it tests whether a byte read by getc() is a digit ('0' to '9') or not.
Here is a modified version:
bool isPrime(int num) {
/* Checks all the numbers before the given input. If the result of
dividing the input by one of those numbers is integer, then the
input is not a prime number. */
int i;
for (i = 2; i < num; i++) {
if (num % i == 0)
return false;
}
return true;
}
Note that it would be much quicker for prime numbers to stop the search when i * i > num:
bool isPrime(int num) {
/* Checks all the numbers before the given input. If the result of
dividing the input by one of those numbers is integer, then the
input is not a prime number. */
int i;
for (i = 2; i * i <= num; i++) {
if (num % i == 0)
return false;
}
return true;
}
I don´t understand the logic of your function. But maybe this help you. Compare the result of the % modulo operation by the result of the division with the floored version of the division´s result, to 0. If it equals 0, return true;, if not return false;.
At long long int res_floored = res; happens an implicit conversion from double to long long int - The value gets floored, f.e. 4.7 to 4. No explicit cast is needed.
Before that, we have to check if the floored double value of the result of the division is capable to be hold in an long long int. Therefore, I compare res to the macros LONG_MAX and LONG_INT, header limits.h, which represent the maximum and minimum integral values a long int can hold. If it doens´t fit we return -1; as error.
int div_result_in_int (double dividend, double divisor);
{
double res = dividend / divisor;
if (res > LONG_MAX || res < LONG_MIN)
{
return -1;
}
long long int res_floored = res;
if (res % res_floored == 0)
{
return true;
}
else
{
return false;
}
}
I use double for both parameters, because the division of two floating-point values can result in an integral value.
#include <stdio.h>
#include <limits.h>
#define true 1
#define false 0
int div_result_in_int (double dividend, double divisor)
{
double res = dividend / divisor;
if (res > LONG_MAX || res < LONG_MIN)
{
return -1;
}
long long int res_floored = res;
if (res == res_floored)
{
return true;
}
else
{
return false;
}
}
int main(void)
{
printf("%d\n", div_result_in_int(8,4));
printf("%d\n", div_result_in_int(9,5));
printf("%d\n", div_result_in_int(3,1));
printf("%d\n", div_result_in_int(97,14));
printf("%d\n", div_result_in_int(2,0.5));
}
Output:
1
0
1
0
1
I have some lines in my code to check whether the resulting value overflows (by comparing it to it's previous iteration), and therefore if the input value is too large. This works for some values, but not for values whose increment is so large that it not only overflows, but overflows so much that the resulting value is larger than the previous iteration. For example, it triggers for 18446744073709551616 (MAX_ULONG + 1), but not for 184467440737095516150 (MAX_ULONG * 10). How can I address this issue? The code is as follows:
unsigned long result = 0;
unsigned long overflowCheck = 0;
int power = 0;
for (int i = (strlen(input) - 1); i >= 0; i--) {
if ((input[i] > ('0' - 1)) && (input[i] < ('9' + 1))) {
result += (input[i] - '0') * (unsigned long)pow(iBase, power++);
} else {
printf("Invalid input string.");
valid = 0;
return -1;
}
if (result < overflowCheck) {
printf("Input value too large.");
valid = 0;
return -1;
}
overflowCheck = result;
}
return result;
There are multiple problems in your code:
you should not use pow to perform integer arithmetics: type double may have less value bits than type unsigned long (for example on 64-bit linux, double has 53 value bits and unsigned long has 64). It is simpler to multiply the current value by iBase and add the digit value for each new digit parsed.
it is easier to detect potential overflow before multiplying or adding the values.
Here is a modified version:
#include <errno.h>
#include <limits.h>
unsigned long atoul(const char *input, unsigned int iBase) {
if (iBase < 2 || iBase > 36) {
errno = EINVAL;
return 0;
}
unsigned long result = 0;
unsigned long maxval = ULONG_MAX / iBase;
int maxdigit = ULONG_MAX % iBase;
for (;;) {
int c = *input++;
int digit;
if (c >= '0' && c <= '9') {
digit = c - '0';
} else
if (c >= 'A' && c <= 'Z') {
digit = c - 'A' + 10;
} else
if (c >= 'a' && c <= 'z') {
digit = c - 'a' + 10;
} else {
break;
}
if (digit >= iBase)
break;
if (result > maxval || (result == maxval && digit > maxdigit) {
/* overflow detected */
errno = ERANGE;
return ULONG_MAX;
}
result = result * iBase + digit;
}
return result;
}
Suppose you want to check if x + y overflows where x and y are both unsigned long. The naive approach would be to do this:
if (ULONG_MAX < x + y)
But this will always be false because of overflow. Instead, you would do this:
if (ULONG_MAX - x < y)
This check is algebraically the same as the first attempt but avoids issues of overflow. You can do a similar check in your case:
if ((input[i] > ('0' - 1)) && (input[i] < ('9' + 1))) {
int digit = input[i] - '0';
if (ULONG_MAX / 10 < result) {
printf("overflow");
return -1;
}
result *= 10;
if (ULONG_MAX - digit < result) {
printf("overflow");
return -1;
}
result += digit;
} else {
printf("Invalid input string.");
valid = 0;
return -1;
}
result < 0 will always return false since result is unsigned (and can never be less than 0. One way to check for overflow is to make sure pow() (as a double) is within the bounds for long. However, the real solution here is to not use pow() and keep everything as integers. If you work starting with the most significant digit, you can multiply result by the base (16 in this case) and add the new digit each time. This works because 1234 = base*(base*(base*(0 + 1) + 2) + 3) + 4
Some (incomplete) code would be:
int input_len = strlen(input);
for (int i = 0; i < input_len; i++) {
// After finding out which digit group input[i] is in:
result = result * iBase + (input[i] - '0');
}
Since result will only change by a factor of 16 at most, you can check for overflow by comparing with the previous result every iteration:
unsigned long previous = result;
// Add in the next digit
if (result < previous) {
// Overflow
}
Suppose I want to add 1+11+111....adding n times.
It is clear that from a certatin value of n, there may be an overflow of the cummulative sum.
Suppose I use the following very simple function to calcuate the sum above:
int calcSum(int num)
{
int sum = 0, sequnt = 1, i;
for (i = 0; i < num; i++)
{
sum += sequnt;
sequnt = (sequnt * 10) + 1;
}
return sum;
}
To that function I want to add a check for overflowing.
I have tried to get some help here How to check if a number overflows an 'int'
but I have to admit it made me confused, and I still find some difficulties with implementing it in my task.
Any help would be appreaciated.
As either of the 2 additions or multiplication are roughly overflow candidates, call a safe overflow checker for each. Use constants in <limits.h> to guide range checking.
#include <limits.h>
int is_undefined_add(int a, int b) {
return (a < 0) ? (b < INT_MIN - a) : (b > INT_MAX - a);
}
int is_undefined_mult(int a, int b) {
if (a > 0) {
if (b > 0) {
return a > INT_MAX / b; // a positive, b positive
}
return b < INT_MIN / a; // a positive, b not positive
}
if (b > 0) {
return a < INT_MIN / b; // a not positive, b positive
}
return a != 0 && b < INT_MAX / a; // a not positive, b not positive
}
int calcSum(int num) {
int sum = 0, sequnt = 1, i;
for (i = 0; i < num; i++) {
if (is_undefined_add(sum, sequnt) Handle_Overflow();
sum += sequnt;
if (is_undefined_mult(sequnt, 10) Handle_Overflow();
sequnt *= 10;
if (is_undefined_add(sequnt, 1) Handle_Overflow();
sequnt++;
}
return sum;
}
is_undefined_add() and is_undefined_mult() are valid for all combinations of int a, int b.
Simply use INT_MAX from limits.h
int calcSum(int num)
{
int sum = 0, sequnt = 1, i;
for (i = 0; i < num; i++)
{
if (INT_MAX - sequnt < sum) exit(1); // overflow
sum += sequnt;
if (INT_MAX/10 <= sequnt) exit(1); // overflow on the two next sentences.
sequnt *= 10;
sequnt++;
}
return sum;
}
The exit(1) is just to make the example short. You can add whatever error handling that you like.
If you are sure you are using two's complement signed integers, then you can check the following: Two positive numbers added must give a positive result and two negative numbers added must give a negative result. It's impossible in only one sum to get two overflows, so if you are adding positive numbers, an overflow will arrive when your result is negative for the first time.
Either case, if you want your code to be portable, then the recommendation is to do something similar to this:
#include <limits.h>
...
if ((a > 0 && b > 0 && MAX_INT - a > b) ||
(a < 0 && b < 0 && MIN_INT - a < b)) {
/* OVERFLOW OF a + b WILL OCCUR */
...
}
if signs of operands are different it is impossible for a + b to be greater than a or b in absolute value, so it is impossible for an overflow to happen.
For unsigneds you have a similar approach (while you save half of the test, as operands can be only positive) but this time the first way is valid always (as standard says unsigned addition is considered a sum module 2^n where n is the wordsize in bits) and in that case you can make the sum and later check if the result is less than any of the operands (if both are positive, sum must be larger than or equal than any of the operands):
unsigned a, b;
...
unsigned sum = a + b;
if (sum < a || sum < b) {
/* OVERFLOW ON a + b HAS HAPPENED */
...
}
You have also to check for integer multiplication overflow. If a and b are to be multiplied, then a*b can overflow. But this time the problem goes further, as overflow can occur more than once, and you cannot do it a posteriori. In that case you can have overflow with equal or different signs, as you are adding a times b (and b has the same sign as itself) if both signs are equal the product will be positive, and overflows will occur
if (MAX_INT/b < a) { /* overflow */ }
if signs are different, the product should be negative, and then
if (MIN_INT/b < a) { /* overflow */ }
if one of the numbers is 0, then no overflow occurs on multipliying, as the result is 0.
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.