x!=x 是实现 std::isnan() 的合法方法吗

问题描述 投票:0回答:2

尽管 Microsoft 博客 claim 否则在我的代码中使用

std::isnan
仍然会生成对 C++ 运行时的调用,而不是内联
ucomiss
。 现在我用
x!=x
检查解决了这个问题(因为在这段代码中性能对我来说很重要),但这让我想知道......如果
x!=x
是检查 NaNess 的方法,那不是一个简单的方法吗?实施
std::isnan

但据我所知,gcc/clang 使用内在函数(并且 msvc 正在尝试)。如果它可以作为正常功能有效实现,他们为什么还要麻烦呢?

所以我有点困惑,因为 SO 上的一个答案声称这是自我比较可以返回 false 的唯一方法。

c++ optimization visual-c++ stl
2个回答
5
投票

C++ 标准委员会(终于?)听取了数字学家关于这一问题的意见。在 C++11 之前,习惯用法

x != x

确实被用来检查 NaN 性。没有其他类别的浮点数值适用于该习惯用法。但它从来没有坐得特别好。首先,一些 NaN 可能会引发异常。它还容易受到错误重构的影响。您还可以假设一些浮点标准,例如常见的 IEEE754。

从 C++11 开始,优先使用

std::isnan


0
投票

std::isnan(x)
(x != x)
并不完全等同。

最初的问题是用 C++ 提出的,但答案也适用于 C。

ISO/IEC TS 18661-1(已纳入即将推出的 C23 标准)澄清了

isnan()
的行为,即即使参数是信号 NaN,该函数也不会引发任何异常。

另一方面,当

(x != x)
是信号 NaN 时,x 表达式抛出“无效操作”异常 (
FE_INVALID
)。

差异仅在于 NaN 信号,因此当信号 NaN 支持关闭时,GCC 会将

std::isnan(x)
优化为
(x != x)
-fno-signaling-nans
,这是默认值)。

这个堆栈溢出问题是相关的:`isnan()` 和测试相等一样快吗?

© www.soinside.com 2019 - 2024. All rights reserved.