C:无序浮点比较不会引发 FE_INVALID
Posted
技术标签:
【中文标题】C:无序浮点比较不会引发 FE_INVALID【英文标题】:C: unordered floating-point comparison does not raise FE_INVALID 【发布时间】:2019-02-07 11:09:13 【问题描述】:我遇到了浮点比较的问题。当使用 <
运算符将值与 NaN 进行比较时,我希望设置 FE_INVALID
标志。 <
运算符应根据 C11 标准(也根据 IEEE-754)升旗:
isless
宏判断它的第一个参数是否小于 它的第二个论点。isless(x, y)
的值始终等于(x) < (y)
;然而,不同于(x) < (y)
,isless(x, y)
不 当x
和y
是引发“无效”浮点异常 无序。
这是一个重现我的问题的示例程序:
#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 都是无序的。
我是否在代码中出错或忘记了某些编译器选项以使行为符合 IEEE 标准?忽略此处引发异常的需要可能是编译器中的错误(或性能优化)吗?
【问题讨论】:
FWIW 与 MSVC 的输出为“FE_INVALID”,c
为 0,尽管我注释掉了 pramga,因为它未被识别。
角落:确保feclearexcept(FE_ALL_EXCEPT);
返回零。
检查__STDC_IEC_559__
。 “定义_STDC_IEC_559_的实现应符合本附件中的规范。” (符合 IEEE 标准?)如果未定义 __STDC_IEC_559__
,则未指定代码以按需要运行。只有错误才是错误的期望。
@WeatherVane 这很奇怪,但至少它对你有用 :) @chux 刚刚检查了feclearexcept
,它返回 0。关于 IEEE 合规性也很好。 (Un)幸运的是,__STDC_IEC_559__
已定义,所以问题出在其他地方..
【参考方案1】:
好的,所以我冒险尝试运行最新的 GCC 版本 (8.2)。
代码在 GCC 8.2.0 下编译时的行为符合预期,因此我假设问题是编译器错误。我没有尝试 7.2.0 和 8.2 之间的其他版本来查看它从什么时候开始工作,但使用 8.2 对我来说已经足够了。
【讨论】:
以上是关于C:无序浮点比较不会引发 FE_INVALID的主要内容,如果未能解决你的问题,请参考以下文章