【发布时间】: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__已定义,所以问题出在其他地方..
标签: c gcc floating-point floating-point-exceptions