gpt4 book ai didi

floating-point - 对于 IEEE754 NaN 值,所有比较返回 false 的基本原理是什么?

转载 作者:行者123 更新时间:2023-12-04 05:51:07 25 4
gpt4 key购买 nike

为什么 NaN 值的比较与所有其他值的表现不同?
也就是说,所有与运算符 ==、<=、>=、<、> 的比较,其中一个或两个值为 NaN,都返回 false,这与所有其他值的行为相反。

我想这在某种程度上简化了数值计算,但我找不到明确说明的原因,甚至在 Lecture Notes on the Status of IEEE 754 中也找不到。由 Kahan 撰写,其中详细讨论了其他设计决策。

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

编辑:
到目前为止的答案都认为比较 NaN 是没有意义的。

我同意,但这并不意味着正确答案是错误的,
相反,它将是一个 Not-a-Boolean (NaB),幸运的是它不存在。

所以在我看来,选择返回 true 或 false 进行比较是任意的,
对于一般数据处理,如果遵守通常的法律将是有利的
(== 的自反性,<、==、> 的三分法),
以免依赖这些规律的数据结构变得困惑。

所以我要求打破这些法律的一些具体优势,而不仅仅是哲学推理。

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

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

while (x != oldX) {
oldX = x;
x = better_approximation(x);
}

然而,最好通过将绝对差异与小限制进行比较来编写。
所以恕我直言,这是打破 NaN 反身性的一个相对较弱的论点。

最佳答案

我是 IEEE-754 委员会的成员,我会尽力帮助澄清一些事情。

首先,浮点数不是实数,浮点运算不满足实数运算的公理。三分法并不是真正算术中唯一不适合浮点数的属性,甚至不是最重要的属性。例如:

  • 加法不是结合的。
  • 分配律不成立。
  • 有没有逆的浮点数。

  • 我可以继续。不可能指定一个固定大小的算术类型来满足我们所知道和喜爱的真实算术的所有属性。 754 委员会必须决定弯曲或打破其中一些。这是由一些非常简单的原则指导的:
  • 如果可以,我们会匹配真正算术的行为。
  • 当我们做不到时,我们会尽量使违规行为可预测且易于诊断。

  • 关于您的评论“这并不意味着正确答案是错误的”,这是错误的。谓词 (y < x)询问是否 y小于 x .如 y是 NaN,那么它不小于任何浮点值 x ,所以答案必然是错误的。

    我提到三分法不适用于浮点值。但是,确实存在类似的属性。 754-2008 标准第 5.11 条第 2 款:

    Four mutually exclusive relations are possible: less than, equal, greater than, and unordered. The last case arises when at least one operand is NaN. Every NaN shall compare unordered with everything, including itself.



    就编写额外的代码来处理 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( ) 之类的编程语言。这可能需要很多年。我将引用 Kahan 自己关于这个主题的文章:

  • Were there no way to get rid of NaNs, they would be as useless as Indefinites on CRAYs; as soon as one were encountered, computation would be best stopped rather than continued for an indefinite time to an Indefinite conclusion. That is why some operations upon NaNs must deliver non-NaN results. Which operations? … The exceptions are C predicates “ x == x ” and “ x != x ”, which are respectively 1 and 0 for every infinite or finite number x but reverse if x is Not a Number ( NaN ); these provide the only simple unexceptional distinction between NaNs and numbers in languages that lack a word for NaN and a predicate IsNaN(x).



    请注意,这也是排除返回“Not-A-Boolean”之类的逻辑。也许这种实用主义放错了地方,标准应该要求 isnan( ) ,但这将使 NaN 几乎不可能在几年内有效和方便地使用,而全世界都在等待编程语言的采用。我不相信这会是一个合理的权衡。

    坦率地说:NaN == NaN 的结果现在不会改变。与其在互联网上提示,不如学会忍受它。如果您想争辩说也应该存在适合容器的顺序关系,我建议您提倡您最喜欢的编程语言实现 totalOrder IEEE-754 (2008) 中标准化的谓词。事实上,它尚未说明卡汉的担忧是正确的,而这种担忧促使当前的事态发展。

    关于floating-point - 对于 IEEE754 NaN 值,所有比较返回 false 的基本原理是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1565164/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com