我想知道数字错误发生在哪一层,在哪一层。 让我用一个例子来解释:
int p = pow(5, 3);
printf("%d", p);
我已经在各种硬件和编译器(VS和GCC)上测试了这些代码,其中一些打印出124,大约125。
AFAIK,pow计算到124.99999999并被截断为int,但是这个错误发生在哪里? 或者,换句话说,校正发生在何处(124.99-> 125)
它是编译器 - 硬件交互吗?
// ******编辑:
这是一个额外的片段(密切关注p = 5,p = 18,......):
#include <stdio.h>
#include <math.h>
int main(void) {
int p;
for (p = 1; p < 20; p++) {
printf("\n%d %d %f %f", (int) pow(p, 3), (int) exp(3 * log(p)), pow(p, 3), exp(3 * log(p)));
}
return 0;
}
答案 0 :(得分:2)
(首先要注意的是,对于IEEE754双精度浮点类型,所有整数,最高可达到2的53次幂。可以精确表示整数pow
不准确性的浮点精度。通常是不正确的。)
pow(x, y)
通常在C中以exp(y * log(x))
实现。因此,它可以“熄灭”。甚至是非常小的整体情况。
对于小积分情况,我通常编写长手计算,而对于其他积分参数,我使用第三方库。虽然使用for
循环的自己动手解决方案很有吸引力,但是对于这样的解决方案可能无法利用的整体能力,可以进行有效的优化。
对于观察到的不同结果,可以使用80位浮点中介来降低某些平台。也许某些计算结果高于125,其他计算结果低于此值。