unusual output from pow

拜拜、爱过 提交于 2019-12-17 21:31:54

问题


The following C code

int main(){
    int n=10;    
    int t1=pow(10,2);
    int t2=pow(n,2);
    int t3=2*pow(n,2);
    printf("%d\n",t1);
    printf("%d\n",t2);
    printf("%d\n",t3);
    return (0);
}

gives the following output

100
99
199

I am using a devcpp compiler. It does not make any sense, right? Any ideas? (That pow(10,2) is maybe something like 99.9999 does not explain the first output. Moreover, I got the same output even if I include math.h)


回答1:


You are using a poor-quality math library. A good math library returns exact results for values that are exactly representable.

Generally, math library routines must be approximations both because floating-point formats cannot exactly represent the exact mathematical results and because computing the various functions is difficult. However, for pow, there are a limited number of results that are exactly representable, such as 102. A good math library will ensure that these results are returned correctly. The library you are using fails to do that.




回答2:


Store the result computations as doubles. Print as double, using %f instead of %d. You will see that the 99 is really more like 99.999997, and this should make more sense.

In general, when working with any floating point math, you should assume results will be approximate; that is, a little off in either direction. So when you want exact results - like you did here - you're going to have trouble.

You should always understand the return type of functions before you use them. See, e.g. cplusplus.com:

double pow (double base, double exponent); /* C90 */

From other answers I understand there are situations when you can expect pow or other floating-point math to be precise. Once you understand the necessary imprecision that plagues floating point math, please consult these.




回答3:


Your variables t1, t2 and t3 must be of type double because pow() returns double.


But if you do want them to be of type int, use round() function.

int t1 = pow(10,2);
int t2 = round(pow(n,2));
int t3 = 2 * round(pow(n,2));

It rounds the returned values 99.9... and 199.9... to 100.0 and 200.0. And then t2 == 100 because it is of type int and so does t3.

The output will be:

100
100
200

Because the round function returns the integer value nearest to x rounding half-way cases away from zero, regardless of the current rounding direction.


UPDATE: Here is comment from math.h:

/* Excess precision when using a 64-bit mantissa for FPU math ops can
cause unexpected results with some of the MSVCRT math functions.  For
example, unless the function return value is stored (truncating to
53-bit mantissa), calls to pow with both x and y as integral values
sometimes produce a non-integral result. ... */


来源:https://stackoverflow.com/questions/16923249/unusual-output-from-pow

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