C:我用pow(10,2)和pow(10,j)获得了不同的结果,j = 2;

时间:2013-10-01 22:06:30

标签: c floating-point pow

这个打印100:

int j=2;
int i= pow(10,2);  
printf("%d\n", i);

这个打印99:

int j=2;
int i= pow(10,j);  
printf("%d\n", i);

为什么?

3 个答案:

答案 0 :(得分:12)

发生的事情是你有一个C实现,其标准库的pow实现质量非常低,即使在类型(double)中可以表示确切的结果,也会返回不精确的结果。对pow(10,2)的调用似乎产生了100.0以下的值,当舍入到整数时,得到99.当参数不变时你没有看到这个的原因是编译器采用了完全优化调用并在编译时用常量100替换它的自由。

如果您的意图是执行整数幂,请不要使用pow函数。写一个正确的整数幂函数,或者当指数已知时,直接写出乘法。

答案 1 :(得分:2)

在第一种情况下,我怀疑编译器已经将值优化为10*10而没有实际调用pow(编译器确实这样做了)。在第二种情况下,看起来您有一个浮点舍入错误。结果是几乎 100但不完全,隐式转换为int会截断它。

pow功能在double上运行,而非int

一般情况下(但并非总是如此),当您将双打转换为整数时,请拨打round()。例如:

int i = (int) round(pow(10,j));

如果您的C库没有此功能,您可以模拟:

#define round(x) floor((x)+0.5)

答案 2 :(得分:0)

pow会返回double,因此如果结果不完全100但略小于转换为int时会截断的结果,您将收到99 1}}你看到的结果。看一下double变量和%f格式的结果会很有趣。

当您使用文字时,您不会看到它的原因是constant folding会导致对pow的调用进行优化并替换为常量。在生成程序集时,我们可以看到使用常量的版本没有调用pow,只是移动了最终结果100看到它live ) :

movl    $100, -4(%rbp)

虽然第二个版本实际调用的版本为pow看到它live ):

call    pow