9

这个打印 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);

为什么?

4

3 回答 3

13

发生的情况是,您有一个 C 实现,其标准库的实现质量非常低pow,即使准确的结果可以用类型 ( double) 表示,它也会返回不精确的结果。调用pow(10,2)似乎产生了下面的值100.0,当四舍五入为整数时,产生 99。当参数为常量时你看不到这一点的原因是编译器冒昧地一起优化调用并替换它在编译时为常数 100。

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

于 2013-10-01T23:08:05.110 回答
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)
于 2013-10-01T22:19:18.683 回答
0

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

使用文字时看不到它的原因是因为常量折叠会导致调用pow被优化并替换为常量。我们可以在生成程序集时看到使用常量的版本,没有调用pow它只是移动最终结果100实时查看):

movl    $100, -4(%rbp)

而第二个版本实际调用的版本pow现场查看):

call    pow
于 2013-10-01T22:24:05.783 回答