负 NaN 不是 NaN?
在编写一些测试用例时,某些测试会检查 NaN 的结果。
我尝试使用 std::isnan
但断言失败:
Assertion `std::isnan(x)' failed.
打印 x
的值后,结果发现它是负 NaN (-nan
)对于我来说这是完全可以接受的。
在尝试使用 NaN != NaN
并使用 assert(x == x)
的事实之后,编译器帮了我一个“忙”并优化了断言。
我自己的 isNaN
函数也正在被优化。
如何检查 NaN 和 -NaN 是否相等?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这很尴尬。
编译器(本例中为 GCC)正在优化比较并且
isnan
返回false
的原因是因为我团队中的某人打开了-ffast-math< /代码>。
从文档中:
注意结尾句子 -
-ffast-math
是不安全的。This is embarrassing.
The reason the compiler (GCC in this case) was optimising away the comparison and
isnan
returnedfalse
was because someone in my team had turned on-ffast-math
.From the docs:
Notice the ending sentence -
-ffast-math
is unsafe.isnan()
预计会对-ffast-math
产生未定义的行为。这是我在测试套件中使用的:
isnan()
is expected to have undefined behaviour with-ffast-math
.This is what I use in my test suite:
对我来说,这看起来像是您的库的
isnan()
实现中的一个错误。它在 Snow Leopard 上的 gcc 4.2.1 上运行良好。然而,尝试一下这个怎么样?显然,我无法测试它,因为
std::isnan(-NaN)
在我的系统上是true
。编辑:使用
-ffast-math
,无论-O
开关如何,雪豹上的gcc 4.2.1都认为NAN = = NAN
为true
,NAN == -NAN
也是如此。这可能会灾难性地破坏代码。我建议放弃-ffast-math
或至少在使用和不使用它的构建中测试相同的结果......This looks like a bug in your library's implementation of
isnan()
to me. It works fine here on gcc 4.2.1 on Snow Leopard. However, what about trying this?Obviously, I can't test it, since
std::isnan(-NaN)
istrue
on my system.EDIT: With
-ffast-math
, irrespective of the-O
switch, gcc 4.2.1 on Snow Leopard thinks thatNAN == NAN
istrue
, as isNAN == -NAN
. This could potentially break code catastrophically. I'd advise leaving off-ffast-math
or at least testing for identical results in builds using and not using it...您应该能够使用 C99 isnan() 。
如果在你的实现中它不能正常工作(那是哪一个?),你可以通过reinterpret_casting到long并执行IEEE位魔法来实现你自己的。
There's C99 isnan() which you should be able to use.
If in your implementation it does not work correctly (which one is that?) you can implement your own, by reinterpret_casting to long and doing IEEE bit magic.
您可以检查数字的位数。 IEEE 754 定义了 NaN 的掩码:
这可能不便于移植,但如果您确定自己的平台,这是可以接受的。更多: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlf101l.doc/xlfopg/fpieee.htm
You can check the bits of number. IEEE 754 has defined mask for NaN:
This might be not portable, but if you are sure about your platfofm it can be acceptable. More: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlf101l.doc/xlfopg/fpieee.htm
这是基于评论中发布的维基百科文章。请注意,它完全未经测试 - 它应该让您了解可以做什么。
编辑:我真的认为你应该考虑向 GLibc 人员提交一个 bug。
This is based off the wikipedia article posted in the comments. Note that it's entirely untested -- it should give you an idea of something you can do though.
EDIT: I really think you should consider filing a bug with the GLibc guys on that one though.