Wrong answer while calculating the nth root of number in cpp

╄→尐↘猪︶ㄣ 提交于 2019-12-02 19:54:18

问题


I am calculating the n'th root of a positive integer using standard library method pow() .Here is the snippet from my program :

double x,y;
x=pow(64,(1.0/3));
int z;
printf("x=%lf\n",x);
z=(int)x;
printf("%d\n",z);

But while finding cube root of 64. X is printed as 4.000000 while z as 3. Why so ?

Can someone suggest a better algorithm , for the same ?


回答1:


If you print more digits on x, you'll see what the problem is (I chose 30 randomly):

double x ;
x = pow(64, 1.0/3);
printf("x=%.30lf\n",x);

Output:

x=3.99999999...999600000000 

So obvisouly, if you cast x into a int it will became 3.

There is not a 'perfect' solution. If you're only dealing with integer, you could create your own root function, but if you want to be able to use float, you'need to deal with accuracy problem due to floating point representation.

There are maybe some C libraries which could help you with this kind of problems.




回答2:


The int override rounds down. Since floating point operations are inaccurate, the calculation may be 3.999999...

Use round(x) to get the correct result.

Since you always want to round down, you can use both floor and (int) -- but you run into the observed error as soon as the instability of floating point calculations results in a slightly less value -- something in the order of 10-15, for double sized calculations. Use a tiny epsilon value to counteract that.

Note that the epsilon "fudge" value below will relate to the number of significant digits in your original number. For larger numbers, you need a smaller epsilon.

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

int main (void)
{
    double x;
    int z;

    x=pow(64,(1.0/3));
    printf("x=%lf\n",x);
    printf("x=%.30lf\n",x);

    z=(int)x;
    printf("%d\n",z);

    z=(int)(x+0.000000000000005);
    printf("%d\n",z);

    x=pow(64,(1.0/4));
    printf("x=%lf\n",x);
    printf("x=%.30lf\n",x);

    z=(int)x;
    printf("%d\n",z);

    z=(int)(x+0.0000000000000005);
    printf("%d\n",z);

    return 1;
}

results, for powers of 1/3 and 1/4, in

x=4.000000
x=3.999999999999999555910790149937
3
4
x=2.828427
x=2.828427124746190290949243717478
2
2



回答3:


As told by @jongware The int override rounds down and floating point operations may be inaccurate .

though you can always do this to evade this problem

def invpow ( n , i):
    x = pow (n ,(1/i))
    if((int)pow((x+1) , i) <= n):
        x += 1;
    print(x)

Or you can write your own method for exponentiation by using Newton - Raphson method described here and here

you can also use Binary search which is quite fast if you have right guess for the range ie (variables high and low )

def invpow( x, n, low, high){
    if(n==1)
        return x;
    mid=(low+high)/2;

    while(low<high){
        mid=(low+high)/2;

        raised=pw(mid,n);

        if(raised==x)
            break;

        if(raised>x)
            high=mid;
        else
            low=mid;

        if(low+1==high){
            mid=low;
            break;
            }

    }
    return mid;
}


来源:https://stackoverflow.com/questions/24105367/wrong-answer-while-calculating-the-nth-root-of-number-in-cpp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!