如果x!=x给出相同的结果,为什么isnan(x)存在?
众所周知,对于任何浮点类型的变量,x != xiff(当且仅当)x是NaN(非数字)。或相反的版本:x == xiffx不是NaN。那么,如果使用语言的自然能力可以获得相同的结果,那么WG14为什么决定定义isnan(x)( math.h) 呢?动机是什么?更好的代码可读性?
额外问题:isnan(x)和之间是否有任何功能差异x != x?
回答
如果使用语言的自然能力可以获得相同的结果?
C 没有指定x == x当当 x 不是NaN。不过,许多实现都是这样做的。C 不需要遵守IEEE_754。 isnan(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 仍未指定,但通常会导致false。 isnan(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 Being excluded the set of objects whose behavior is defined gives no guarantees. Even if that might feel unsatisfying.
- @AndrewHenle Excluding something from a guarantee just excludes it. It does not guarantee the opposite, or even something else.
- @AndrewHenle That's where you go wrong. They are only excluded from the set guaranteed to compare equal.
- @AndrewHenle The sentence is about two values with the same object representations, excluding those that are NaN. Not following it with a sentence about those excluded values might confuse those assuming everything to be rigidly defined, without room to accommodate different implementations. A mind-set somewhat alien to C.