Lir*_*una 29 c++ nan fast-math
在编写一些测试用例时,有些测试会检查NaN的结果.
我尝试使用std::isnan但断言错误:
Assertion `std::isnan(x)' failed.
Run Code Online (Sandbox Code Playgroud)
打印出值后x,结果显示它是负NaN(-nan),在我的情况下是完全可以接受的.
在尝试使用NaN != NaN和使用的事实之后assert(x == x),编译器给我一个'恩惠'并优化断言.
制作我自己的isNaN功能也正在优化.
如何检查NaN 和 -NaN的相等性?
Lir*_*una 33
这很尴尬.
编译器(在这种情况下是GCC)优化远离比较并isnan返回的false原因是因为我团队中的某个人已经打开了-ffast-math.
来自文档:
-ffast-math
Sets -fno-math-errno, -funsafe-math-optimizations,
-fno-trapping-math, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans and fcx-limited-range.
This option causes the preprocessor macro __FAST_MATH__ to be defined.
This option should never be turned on by any -O option since it can result in incorrect output for programs which depend on an exact implementation of IEEE or ISO rules/specifications for math functions.
注意结束语 - -ffast-math不安全.
isnan()预计会有未定义的行为-ffast-math。
这是我在测试套件中使用的:
#if defined __FAST_MATH__
# undef isnan
#endif
#if !defined isnan
# define isnan isnan
# include <stdint.h>
static inline int isnan(float f)
{
union { float f; uint32_t x; } u = { f };
return (u.x << 1) > 0xff000000u;
}
#endif
Run Code Online (Sandbox Code Playgroud)