Floating point IEEE754 NaN值的所有比较返回false的理由是什么?

Floating point IEEE754 NaN值的所有比较返回false的理由是什么?,floating-point,comparison,nan,ieee-754,iec10967,Floating Point,Comparison,Nan,Ieee 754,Iec10967,为什么NaN值的比较行为不同于所有其他值? 也就是说,与所有其他值的行为相反,与运算符==、=(其中一个或两个值均为NaN)进行的所有比较返回false 我想这在某种程度上简化了数值计算,但我找不到一个明确的理由,甚至在卡汉详细讨论其他设计决策的文章中也找不到 在进行简单的数据处理时,这种异常行为会造成麻烦。例如,在对C程序中的某个实值字段的记录列表进行排序时,我需要编写额外的代码来处理NaN作为最大元素,否则排序算法可能会变得混乱 编辑: 到目前为止,所有的答案都认为比较南部是没有意义的 我同

为什么NaN值的比较行为不同于所有其他值? 也就是说,与所有其他值的行为相反,与运算符==、=(其中一个或两个值均为NaN)进行的所有比较返回false

我想这在某种程度上简化了数值计算,但我找不到一个明确的理由,甚至在卡汉详细讨论其他设计决策的文章中也找不到

在进行简单的数据处理时,这种异常行为会造成麻烦。例如,在对C程序中的某个实值字段的记录列表进行排序时,我需要编写额外的代码来处理NaN作为最大元素,否则排序算法可能会变得混乱

编辑: 到目前为止,所有的答案都认为比较南部是没有意义的

我同意,但这并不意味着正确答案是错的, 相反,它将是一个非布尔(NaB),幸运的是它并不存在

因此,在我看来,选择返回真或假进行比较是武断的, 对于一般的数据处理来说,如果遵循通常的规律,这将是有利的 (自反性==,三分法), 以免依赖这些定律的数据结构变得混乱

所以我要求的是打破这些定律的一些具体好处,而不仅仅是哲学推理

编辑2: 我想我现在明白了为什么把NaN设为最大值是个坏主意,它会搞乱上限的计算

南!=NaN可能需要避免在循环中检测到收敛,例如

while (x != oldX) {
    oldX = x;
    x = better_approximation(x);
}
但是,最好通过比较绝对差异和一个小限值来编写。
因此,我认为这是一个相对较弱的论点,用来打破NaN的自反性。

我猜NaN(不是一个数字)的确切意思是:这不是一个数字,因此比较它没有意义

这有点像SQL中带有
null
操作数的算术:它们都会导致
null


浮点数的比较用于比较数值。因此,它们不能用于非数值。因此,NaN不能在数字意义上进行比较。

NaN可以被认为是一个未定义的状态/数字。类似于0/0未定义或sqrt(-3)(在浮点所在的实数系统中)的概念

NaN用作此未定义状态的某种占位符。从数学上讲,未定义并不等于未定义。也不能说一个未定义的值大于或小于另一个未定义的值。因此,所有比较都返回false


在比较sqrt(-3)和sqrt(-2)的情况下,这种行为也是有利的。它们都将返回NaN,但即使返回相同的值,它们也不相等。因此,在处理NaN时,让相等总是返回false是理想的行为。

再加上另一个类比。如果我递给你两个盒子,告诉你两个盒子里都没有苹果,你能告诉我盒子里装的是同一个东西吗


NaN不包含关于某事物是什么的信息,只包含它不是什么的信息。因此,这些元素绝对不能说是相等的。

从上一篇维基百科文章中可以看出,以下做法可能导致NAN:

  • 至少有一个操作数为NaN的所有数学运算>
  • 0/0分区,∞/∞, ∞/-∞, -∞/∞, 及-∞/-∞
  • 乘法0×0∞ 和0×-∞
  • 补充∞ + (-∞), (-∞) + ∞ 和等价减法
  • 将函数应用于其域外的参数,包括取负数的平方根,取负数的对数,取90度(或π/2弧度)的奇数倍的正切,或取小于-1或大于+1的数字的反正弦或余弦

由于无法知道这些操作中的哪一个创建了NaN,因此无法对它们进行有意义的比较。

这看起来很奇怪,因为大多数允许NaN的编程环境也不允许三值逻辑。如果将三值逻辑加入到混合中,它将变得一致:

  • (2.7==2.7)=正确
  • (2.7==2.6)=错误
  • (2.7==NaN)=未知
  • (NaN==NaN)=未知

即使是.NET也没有提供
bool?操作符==(双v1,双v2)
操作符,因此您仍然会被愚蠢的
(NaN==NaN)=false
结果所困扰。

我不知道设计原理,但以下是IEEE 754-1985标准的摘录:


"即使操作数的格式不同,也可以比较所有支持格式的浮点数。比较是精确的,不会溢出或下溢。可以有四种互斥关系:小于、等于、大于和无序。最后一种情况是至少有一个操作数为NaN。每个NaN都应进行比较“我是IEEE-754委员会的成员,我将尝试帮助澄清一些事情

首先,浮点数不是实数,浮点运算不符合实数运算的公理。三分法不是实数运算中唯一不适用于浮点数的属性,甚至不是最重要的属性。例如:

  • 加法不是关联的
  • 分配规律不成立
  • 有些浮点数没有倒数
我可以接着说。不可能指定一个固定大小的算术类型来满足我们所知道和喜爱的所有实数算术属性。754委员会必须决定弯曲或破坏其中的一些。这是由一些非常简单的原则指导的:

  • 当我们可以的时候,我们匹配真实算术的行为
  • 当我们做不到的时候,我们试着做vi