【发布时间】:2015-10-19 08:45:36
【问题描述】:
我想知道数字错误发生在哪里,在哪一层。 让我用一个例子来解释:
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)
是编译器-硬件交互吗?
//******已编辑:
这里还有一个可以玩的 sn-p(请留意 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;
}
【问题讨论】:
-
计算机上的浮点值是一件复杂的事情,对它们的运算结果取决于很多事情。例如,硬件支持(如果有)、不同软件(编译器、标准库)或硬件使用的舍入算法,以及许多其他东西。
-
另外请注意,当使用常量表达式时,编译器通常会use builtin functions,因此您可能还想尝试使用
-fno-builtin看看这是否会影响结果。 -
我相信不是,我刚刚使用 for 循环添加了一个 sn-p 并且发生了同样的事情。
-
为什么要截断为
int?你为什么使用带有整数指数的pow?这些才是真正要问的问题。 -
没错,但正如我所说 - 我知道这不是最佳做法,我肯定不会提倡这样做。附带说明一下,当一名学生试图计算一个数字是否是阿姆斯特朗数字 (cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/arms.html) 时,这个问题就出现了。这是一个诚实的错误,尤其是对学生而言。