sta*_*lue 240 floating-point comparison nan ieee-754 iec10967
为什么NaN值的比较与所有其他值的行为不同?也就是说,与运算符==,<=,> =,<,>的所有比较(其中一个或两个值为NaN)返回false,这与所有其他值的行为相反.
我想这可以通过某种方式简化数值计算,但我找不到明确说明的理由,甚至在Kahan 的IEEE 754状态讲义中也没有详细讨论其他设计决策.
这种异常行为在进行简单数据处理时会造成麻烦.例如,当在C程序中对某些实值字段的记录列表进行排序时,我需要编写额外的代码来处理NaN作为最大元素,否则排序算法可能会变得混乱.
编辑: 迄今为止的答案都认为比较NaNs毫无意义.
我同意,但这并不意味着正确的答案是错误的,而是一个非布尔值(NaB),幸运的是它不存在.
因此,在我看来,选择返回真或假的比较是任意的,对于一般数据处理,如果它遵循通常的定律(==的反射性,<= =,>的三分法),那将是有利的,以免数据结构依赖这些法律变得困惑.
因此,我要求打破这些法律的一些具体优势,而不仅仅是哲学推理.
编辑2: 我想我现在理解为什么使NaN最大化是一个坏主意,它会搞砸上限的计算.
可能需要NaN!= NaN以避免检测环路中的收敛,例如
while (x != oldX) {
oldX = x;
x = better_approximation(x);
}
Run Code Online (Sandbox Code Playgroud)
然而,最好通过比较绝对差异与小限制来编写.所以恕我直言,这是打破NaN反身性的一个相对弱的论据.
Ste*_*non 481
我是IEEE-754委员会的成员,我会尽力帮助澄清一些事情.
首先,浮点数不是实数,浮点运算不满足实数算术的公理.三分法不是真正算术的唯一属性,它不适用于浮点数,甚至也不是最重要的.例如:
我可以继续 不可能指定一个固定大小的算术类型来满足我们所熟知和喜爱的所有实际算术属性.754委员会必须决定弯曲或打破其中一些.这是由一些非常简单的原则指导:
关于你的评论"这并不意味着正确答案是错误的",这是错误的.谓词(y < x)询问是否y小于x.如果y是NaN,则它不小于任何浮点值x,因此答案必然是错误的.
我提到三分法不适用于浮点值.但是,有一个类似的属性确实成立.754-2008标准第5.11条第2款:
四种相互排斥的关系是可能的:小于,等于,大于和无序.当至少一个操作数是NaN时,出现最后一种情况.每个NaN都应该将无序与包括其自身在内的所有东西进行比较.
至于编写额外的代码来处理NaN,通常可能(虽然并不总是很容易)以一种NaN正确落入的方式构造代码,但情况并非总是如此.如果不是这样,可能需要一些额外的代码,但这对于代数闭包带来浮点运算的便利性来说是一个很小的代价.
附录:许多评论者认为,保持平等和三分法的反身性更为有用,理由是采用NaN!= NaN似乎并没有保留任何熟悉的公理.我承认对这个观点有一些同情,所以我想我会重新审视这个答案,并提供更多的背景.
我与Kahan谈话的理解是NaN!= NaN起源于两个实用的考虑因素:
这x == y应该等同于x - y == 0任何可能的(除了作为真实算术的定理之外,这使得比较的硬件实现更节省空间,这在标准开发时是最重要的 - 但请注意,这违反了x = y =无穷大,所以它本身并不是一个很好的理由;它可以合理地弯曲到(x - y == 0) or (x and y are both NaN)).
更重要的是,当时没有isnan( )断言NaN在8087算术中被形式化; 有必要为程序员提供一种方便有效的检测NaN值的方法,这些方法不依赖于编程语言,提供isnan( )可能需要很多年的东西.我将引用卡汉自己关于这个主题的文章:
如果没有办法摆脱NaNs,它们就像CRAYs上的Indefinites一样无用; 一旦遇到一个人,计算将最好停止,而不是无限期地持续到无限期结束.这就是为什么NaN上的某些操作必须提供非NaN结果的原因.哪个操作?......例外是C谓词"x == x"和"x!= x",对于每个无限或有限数x,它们分别为1和0,但如果x不是数字(NaN)则反向; 这些提供了NaNs与缺少NaN单词和谓词IsNaN(x)的语言中数字之间唯一的简单区分.
请注意,这也是排除返回"Not-A-Boolean"之类的逻辑.也许这种实用主义是错误的,标准应该是必需的isnan( ),但是这将使NaN几乎不可能在世界等待编程语言采用的情况下有效和方便地使用几年.我不相信那是一次合理的权衡.
直言不讳:NaN == NaN的结果现在不会改变.更好地学会忍受它而不是在互联网上抱怨.如果你想争论一个适合容器的订单关系也应该存在,我建议你提倡你最喜欢的编程语言实现totalOrderIEEE-754(2008)标准化的谓词.事实上,它还没有谈到Kahan关注的有效性,这种关注促成了当前的事态.
小智 49
NaN可以被认为是未定义的状态/数字.类似于0/0未定义或sqrt(-3)的概念(在浮点所在的实数系统中).
NaN用作此未定义状态的一种占位符.从数学上讲,undefined不等于undefined.你也不能说未定义的值大于或小于另一个未定义的值.因此,所有比较都返回错误.
在将sqrt(-3)与sqrt(-2)进行比较的情况下,此行为也很有用.他们都会返回NaN,但即使他们返回相同的值,他们也不是等价的.因此,在处理NaN时,等式总是返回false是期望的行为.
Jac*_*yan 34
再说一个类比.如果我递给你两个盒子,告诉你它们都没有苹果,你会告诉我盒子里面有同样的东西吗?
NaN不包含有关什么是什么的信息,而不包含什么.因此,这些元素绝对不能说是平等的.
Ste*_*sek 12
从关于NaN的维基百科文章中,以下实践可能会导致NaN:
由于无法知道哪些操作创建了NaN,因此没有办法比较它们是否有意义.
我不知道设计原理,但这是 IEEE 754-1985 标准的摘录:
“即使操作数的格式不同,也可以比较所有支持格式的浮点数。比较是精确的,不会上溢或下溢。可能有四种互斥关系:小于、等于、大于和无序.最后一种情况出现在至少一个操作数是 NaN 时。每个 NaN 都应与所有内容进行无序比较,包括它自己。”
| 归档时间: |
|
| 查看次数: |
42401 次 |
| 最近记录: |