0

Here is my code for getting the root of 2

#include <stdio.h>
unsigned long long root(int n);
int main()
{
    int n,i;
    unsigned long long c;
    n=10;
    for(i=1;i<=n;i++)
    {
        c=root(i);
        printf("%d decimal digits:%llu\n",i,c);
    }
    return 0;
}

unsigned long long root(int n)
{   unsigned long long int m,d;
    d=pow(10,n);
    m=2*pow(10,2*n);
    while (pow(d,2)<=m)
    {
        d++;
    }
    return d-1;

}

Unsigned long long int can support from 0 to $2^64-1$. I think this enough to calculate 10 digits decimal.

I expect the output of 10 digits decimal should be 14142135623

kile
  • 141
  • 1
  • 7
  • 2
    What is the actual output of your program? What is the expected output? Have you tried to step through the code in a debugger? – Some programmer dude Nov 01 '20 at 03:00
  • 1
    Also, `pow` returns a `double` which can vastly exceed the storage of `unsigned long long` causing the result to be reduced modulo until it fits in either `d` or `m`. (in your case the limit of `10` should keep things in range -- but if you change `n` be aware...) – David C. Rankin Nov 01 '20 at 03:04
  • 1
    `pow` is meant for floating point powers, not integer powers. `double` only has 53 bits of precision. – Nate Eldredge Nov 01 '20 at 03:06
  • https://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int may interest you. – Nate Eldredge Nov 01 '20 at 03:10
  • @Someprogrammerdude `10` digits decimal should be `14142135623` – kile Nov 01 '20 at 03:12

1 Answers1

5
  1. You're actually going to 10 ** 20, not 10 ** 10, because of this line, which uses 2 * n (where the n you pass goes to 10):

    m=2*pow(10,2*n);
    

    So even ignoring your other issue, this wouldn't work (2 ** 64 isn't enough to handle 20 digits).

  2. pow is implemented in terms of double, and double typically only has 53 bits of integer precision. So you're not actually getting 64 bits of precision.

If you want to do integer exponentiation with numbers beyond what double can accurately represent, you'll need to write your own integer-based pow.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • I just want 15 digits. – kile Nov 01 '20 at 03:12
  • 1
    @kile: Yeah, standard IEEE 754 binary floating point (what `double` is typically implemented as) can't reach the top end of 15 digits. So you can't use `pow`. Write your own integer `pow`. Or just move to using GMP and avoid the limitations of C standard types. – ShadowRanger Nov 01 '20 at 03:17