C:无序浮点比较不会引发FE_INVALID

时间:2019-02-07 11:09:13

标签: c gcc floating-point floating-point-exceptions

我遇到了浮点比较的问题。当使用<运算符将值与NaN进行比较时,我希望设置FE_INVALID标志。 <运算符应根据C11标准(也根据IEEE-754)引发标志:

  

isless宏确定其第一个参数是否小于   它的第二个论点。 isless(x, y)的值始终等于   (x) < (y);但是,(x) < (y) 不同,isless(x, y)与   当xy分别为引发“无效”浮点异常   无序

这是一个重现我的问题的示例程序:

#include <stdio.h>
#include <math.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON

int main()
{
    volatile float a = 12.0f;
    volatile float b = NAN;
    volatile int   c;

    feclearexcept(FE_ALL_EXCEPT);

    c = (a < b);

    if (fetestexcept(FE_INVALID))
        printf("FE_INVALID\n");
    else
        printf("Not invalid\n");

    return 0;
}

在我的机器(Linux,march=broadwell)上,它返回“ Not invalid”。 我使用GCC v7.2.0使用-std=c11选项进行了编译(不使用它并不会改变结果)。发出的x86指令是UCOMISS,它仅引发信号通知NaN的异常-我希望看到COMISS,因为这会引发所有NaN比较的异常,因为无论NaN是否是无序的,NaN都是无序的是否发信号。

我是否在我的代码中犯了一个错误或忘记了一些编译器选项来使行为符合IEEE?忽略这里引发异常的需要是编译器中的错误(或性能优化)吗?

1 个答案:

答案 0 :(得分:2)

好的,所以我大吃一惊,并运行了最新的GCC版本(8.2)。

GCC 8.2.0 下编译时,代码的行为符合预期,因此我假设问题是编译器错误。我没有尝试过7.2.0到8.2之间的其他版本来查看它何时开始工作,但是使用8.2对我来说已经足够了。