C:我用pow(10,2)和pow(10,j)获得了不同的结果,j = 2;
这个打印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);
为什么?
发生的事情是你有一个C实现,其标准库具有非常低质量的pow
实现,即使在类型( double
)中可以表示确切的结果,也会返回不精确的结果。 对pow(10,2)
的调用似乎产生了刚好低于100.0
的值,当舍入到整数时,产生99.当参数是常量时你没有看到这个的原因是编译器冒昧地全部优化调用并在编译时用常量100替换它。
如果您的意图是执行整数幂,请不要使用pow
函数。 写一个适当的整数幂函数,或者当指数已知时,直接写出乘法。
在第一种情况下,我怀疑编译器已经将值优化为10*10
而没有实际调用pow
(编译器确实这样做)。 在第二种情况下,看起来您有一个浮点舍入错误。 结果几乎是100但不完全,并且隐式转换为int
截断它。
pow
函数运行double
,而不是int
。
通常(但不总是),当您将双精度转换为整数时,您调用round()
。 例如:
int i = (int) round(pow(10,j));
如果您的C库没有此function,您可以模拟:
#define round(x) floor((x)+0.5)
pow
返回double
,因此如果结果不是100
但略小于转换为int
时将截断的结果,您将收到您看到的99
结果。 看看double
变量和%f
格式的结果会很有趣。
当你使用文字时你不会看到它的原因是因为常量折叠会导致对pow
的调用被优化并被常量替换。 当我们生成程序集时,我们可以看到使用常量的版本没有调用pow
它只是移动最终结果100
( 看到它实时 ):
movl $100, -4(%rbp)
而版本第二个版本实际上称为pow
( 见它直播 ):
call pow