0

I have used this code to generate root, if output is not integer it should return -1.

#include <stdio.h>
#include <math.h>
int main(){
    long int n=0;
    long int num,p,reti;
    double ret;
    scanf("%ld",&n);
    while(n!=0){
        scanf("%ld %ld",&p,&num);
        ret=pow(num,(double)1/p);
        reti=(int)ret;
        printf("%lf %lf\n",ret,(double)reti);
        if(ret!=(double)reti){
            reti=-1;
        }
        printf("%ld\n",reti);
        n=n-1;

    }
    return 0;

}

but if I give input as

1
5  3125

it should give 5, but it is giving -1.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Please reformat your post so we can read the code in a code block. Ie add spaces in front to each code line! – Mike Wodarczyk Feb 12 '17 at 05:22
  • keep variable names understandable !what is n,p,num...why not keep it like number , power – minigeek Feb 12 '17 at 05:28
  • what does the earlier printf line show? I would suspect that the pow function returns something close to 5 but not exactly 5.0000000000. (eg 5.00000000001) Then when you (int) it and get 5 and convert this back to a double you see that 5.0000000000 != 5.00000000001. – Mike Wodarczyk Feb 12 '17 at 05:34
  • 1/5 is not exactly representable in binary floating-point, so even if you assume that `pow()` will produce an answer within one half ULP of the exact one *for the computation you are performing*, that answer may not be exactly 5, because the power is not exactly 0.2. – John Bollinger Feb 12 '17 at 05:35

2 Answers2

1

ret is not exactly 5.00000, you're just not printing enough digits after the decimal point to see the difference. Change your format to %.20lf and it will show 5.00000000000000088818, which is not equal to (double)5.

This is because pow() works with floating point numbers, and there are some inaccuracies introduced. (double)1/5 can't be represented exactly in binary floating point. See Is floating point math broken?

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

The reason why is this block of code:

if(ret!=(double)reti){
    reti=-1;
}

reti is some integer value - converting it to double will convert it to a double representation, but odds are good that it will not be exactly equal to ret. This is a common issue with floating point numbers - generally speaking, you should never compare pure equality. Instead, you should compare the difference between the two numbers and confirm that it's within some acceptable error range (e.g. 0.00001).

Caleb
  • 1,143
  • 5
  • 13