如果 x != x 给出相同的结果,为什么 isnan(x) 存在?

Pav*_*kin 8 c nan ieee-754

众所周知,对于任何浮点类型的变量,x != xiff(当且仅当)xNaN(非数字)。或相反的版本:x == xiffx不是NaN。那么,如果使用语言的自然能力可以获得相同的结果,那么WG14为什么决定定义isnan(x)( math.h) 呢?动机是什么?更好的代码可读性?

额外问题:isnan(x)和之间是否有任何功能差异x != x

chu*_*ica 17

如果使用语言的自然能力可以获得相同的结果?

C 没有指定x == x当当 x 不是NaN。不过,许多实现都是这样做的。C 不需要遵守IEEE_754isnan(x)定义明确。

使用isnan(x)可移植代码。


类型表示中的C (自 C99 起)具有

具有相同对象表示的两个值(NaN 除外)比较相等,但比较相等的值可能具有不同的对象表示。

... 但这并没有指定比较 2 个 NAN 的行为。


__STDC_IEC_559__(类似于遵守 IEEE-754)被定义为 1(C 不需要的东西),那么

“如果 x 是 NaN,则表达式 x != x 为真。”

“如果 x 是 NaN,则表达式 x == x 为假。”

__STDC_IEC_559__未定义为 1 时,请谨慎假设浮点数学边缘的行为,例如NAN相等。


[编辑以解决一些评论]

C,在 FP 数学的角落,缺乏 IEEE-754 的细节。正如对 IEEE-754 的引用所证明的那样,C89 允许 NAN,但缺乏isnan(x). 没有“具有相同对象表示的两个值(NaN 除外)比较相等,......”来指导。当时,x==x对于 NAN 没有指定。使用 C99,而不是破坏或使先前的代码无效,isnan(x)被定义为明确的 NAN 测试。在我看来,x==x对于 NAN 仍未指定,但通常会导致falseisnan(x)还提供了代码清晰度。关于 C 和 NAN 的很多内容都是模糊的:往返有效载荷序列信令编码/识别、NAN 可用性……


isnan(x)和之间是否有任何功能差异x != x

除了上面讨论的isnan(x)vs定义明确的功能x != x之外,还有一些模糊的功能:

  • isnan(x)对 评估x一次和两次x != x。如果x是像y++.

  • isnan(x)语义类型进行操作。当“实现支持评估类型中的 NaN 但不支持语义类型中的 NaN”时,这会有所不同。 x != x对评估类型进行操作。研究FLT_EVAL_METHOD更多细节。

  • @AndrewHenle 被排除在外的行为已定义的对象集不能提供任何保证。即使这可能会让人感到不满意。 (3认同)
  • @AndrewHenle 从保证中排除某些内容只是将其排除。它不能保证相反的情况,甚至不能保证其他的情况。 (2认同)
  • @AndrewHenle 这就是你出错的地方。它们仅被排除在保证比较相等的集合之外。 (2认同)
  • @AndrewHenle 这句话是关于具有相同对象表示的两个值,不包括 NaN 的值。后面不跟上关于那些被排除的值的句子可能会让那些假设一切都被严格定义、没有空间容纳不同实现的人感到困惑。与 C 有点不同的思维方式。 (2认同)