c

时间:2015-10-19 08:45:37

标签: c gcc precision pow

我想知道数字错误发生在哪一层,在哪一层。 让我用一个例子来解释:

int p = pow(5, 3);
printf("%d", p);

我已经在各种硬件和编译器(VS和GCC)上测试了这些代码,其中一些打印出124,大约125。

  • 在相同的硬件(OS)上,我在不同的编译器(VS和GCC)中得到不同的结果。
  • 在不同的HW(OS)上,我在同一个编译器(cc(GCC)4.8.1)中得到不同的结果。

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;
}

1 个答案:

答案 0 :(得分:2)

(首先要注意的是,对于IEEE754双精度浮点类型,所有整数,最高可达到2的53次幂。可以精确表示整数pow不准确性的浮点精度。通常是不正确的。)

pow(x, y)通常在C中以exp(y * log(x))实现。因此,它可以“熄灭”。甚至是非常小的整体情况。

对于小积分情况,我通常编写长手计算,而对于其他积分参数,我使用第三方库。虽然使用for循环的自己动手解决方案很有吸引力,但是对于这样的解决方案可能无法利用的整体能力,可以进行有效的优化。

对于观察到的不同结果,可以使用80位浮点中介来降低某些平台。也许某些计算结果高于125,其他计算结果低于此值。