c - 我的浮点代码或 gcc 中有错误吗?

标签 c gcc floating-point

以下代码在 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/

相关文章:

c - 查找连接到/dev/input/eventX 的设备的描述

C - 尝试发送()数据但有错误

c - 使用 `const` 元素设计 C 容器?

c++ - 链接器错误 : wants C++ virtual base class destructor

gcc - 内核编译错误 : gcc: error: elf_i386: No such file or directory

c - do while 循环 C 编码错误

c++ - 了解 cin.fail() 和 cin.clear - vector 附加程序

c++ - 使用 gcc 编译时 PowerPC 上的 long double 错误

c++ - NaN 在 float 和 double 之间的类型转换

lisp - 如何在 Lisp 中将有理数显示为一长串数字?