以下代码在 64 位下按预期工作,但在 32 位下在 -O2 和 -O3 下失败,预期输出为 1.1,在有漏洞的系统下它打印 1.0。我试图确定这是否是我的代码中的错误(对 float 的工作方式做出了一些错误的假设)或 GCC 中的错误。如果它在我的代码中,我究竟该如何修复它?
#include <math.h>
#include <stdio.h>
int f(double x) {
return isinf(1.0 / x);
}
int m_isinf(double x) {
return x != 0 && x * 0.5 == x;
}
int g(double x) {
return m_isinf(1.0 / x);
}
double values[] = {
5.5e-309,
-1.0
};
int main() {
int i;
for (i = 0; values[i] != -1.0; i++) {
printf("%d\n", f(values[i]));
printf("%d\n", g(values[i]));
}
return 0;
}
最佳答案
表达式的计算精度可能高于类型。在您的 32 位构建中,编译器可能正在使用 80 位长 double (在 64 位中不再使用)来计算 x != 0 && x * 0.5 == x
。
(GCC 知道这个规则的问题,在它不能的上下文中更精确地评估)。
C99 中的 6.3.1.8/2(C90 中的 6.2.1.5 等效):
The values of floating operands and of the results of floating expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby
在一致的实现中:
int m_isinf(double x) {
double const half_x = x * 0.5;
return x != 0 && half_x == x;
}
应该可以。但是 gcc 错误(http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 查看重复的数量)经常阻止它工作。错误报告中有一些解决方法。
关于c - 我的浮点代码或 gcc 中有错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5660691/