为啥无穷大 × 0 = NaN?

Posted

技术标签:

【中文标题】为啥无穷大 × 0 = NaN?【英文标题】:Why is Infinity × 0 = NaN?为什么无穷大 × 0 = NaN? 【发布时间】:2016-10-16 21:52:12 【问题描述】:

IEEE 754 将 1 / 0 的结果指定为 ∞(无穷大)。

但是,IEEE 754 然后将 0 × ∞ 的结果指定为 NaN。

这感觉反直觉:为什么 0 × ∞ 不是 0?

    我们可以将 1 / 0 = ∞ 视为 1 / z 的极限,因为 z 趋于零

    我们可以将 0 × ∞ = 0 视为 0 × z 的极限,因为 z 趋于 ∞。

为什么 IEEE 标准遵循直觉 1. 而不是 2.?

【问题讨论】:

因为无穷大不是一个具体的数字? Infinity * 0 isn't so easily defined. 但是在Infinity / 0 的情况下,除以零是否优先于分子中发生的任何事情? (我在这里不是在严格地争论数学。我只是在猜测语言作者的意图。) Infinity is javascript 中的一个数字,至少按类型来说是这样,但它并不是一个具体的数字,它不是 7 或类似的东西,更多的是一个概念,“最大的数” 等等。当你将无穷大与任何正数或负数相乘时,你会得到正无穷或负无穷,因为它不能更大。当您将一个数字除以 Infinity 时,您会得到 0,因为它不能再小了。当您将 Infinity 与 0 相乘时,您会得到“不是数字”,因为有人认为这是合乎逻辑的做法,并将其放入规范中。 为什么不将 0*Infinity 视为 x*infinity 的极限,因为 x 趋于零?反过来说,这也很有意义。 0*Infinity 的问题,以及它应该是 NaN 的原因是,有可能为 0、Infinity 以及介于两者之间的任何东西想出一个案例。 【参考方案1】:

如果您不认为 IEEE 754 浮点零和无穷大的行为实际上是零或无穷大,则更容易理解它们的行为。

浮点零不仅代表实数零。它们还代表所有会舍入到小于最小次正规数的实数。这就是为什么签名为零的原因。如果它们实际上不是零,即使很小的数字也有符号。

同样,每个无穷大也代表所有具有相应符号的数字,这些数字会四舍五入到一个大小不适合有限范围的数字。

NaN 表示“没有实数结果”,例如 sqrt(-1),或“没有线索”。

非常大的东西除以非常小的东西是非常非常大的,所以`Infinity / 0 == Infinity"。

非常大的东西乘以非常小的东西可能是任何东西,这取决于我们不知道的实际大小。由于结果可能是从非常小到非常大的任何值,NaN 是最合理的答案。

================================================ ===================

虽然我认为以上是理解实际浮点行为的最佳方式,但在实数限制中也会出现类似的问题。

假设f(x) 趋于无穷,g(x) 趋于零,因为x 趋于无穷。很容易证明f(x)/g(x) 趋于无穷,正如x 趋于无穷。另一方面,如果没有更多关于函数的信息,就无法证明f(x)*g(x) 的极限。

【讨论】:

所以我们应该将 0 视为一个非常小的数量,而不是实际的 0,因为它是许多算术计算的结果,会发生算术下溢?这似乎是明智的! 我不同意这个答案。认为浮点数代表小范围的值是很多混乱的根源,我们不应该鼓励它。零正好代表零(这是 OP 没有问题的事实,否则他们不会接受 0 倍任何东西都应该如此容易地为零),无穷大在概念上表示超出所有实数的异常值(这是 OP 尚未接受的点)。 @PascalCuoq 在您的模型中,负零是什么,为什么存在? @PascalCuoq 永远不要将浮点值与“==”进行比较是没有意义的,而且这个“规则”会在没有正当理由的情况下盲目重复,而不是求助于“小区间”模型,就我见过。据我所知,-0 的存在不仅仅是为了格式正交性的方便,而是通过有意识的设计:参见 Kahan 关于复杂函数中的分支切割的论文,-0 表示从下方接近零时的极限;也用于与无穷大的平滑交互,例如1/x 其中 x 为负数且下溢。不产生唯一标识binary64 不必要的数字对我来说似乎没问题? 我对浮点数的看法类似于物理学中的波/粒二元论:有时最好将 fp 数视为一个点,而其他时候最好将其视为间隔,取决于上下文。在处理三角函数的大参数时,库编写者不知道哪个上下文相关视图是合适的,因此需要在保守(点)方面犯错。至于 sqrt(-0)==0,我不记得是什么驱动了它,在“负半平面接近零(通过下溢)”心理模型下没有意义,但需要与 + 保持一致0==-0?

以上是关于为啥无穷大 × 0 = NaN?的主要内容,如果未能解决你的问题,请参考以下文章

为啥“np.inf // 2”会导致 NaN 而不是无穷大?

C++中非数nan的定义与范例

我们如何比较算术运算的结果是 NaN 还是无穷大..?

除以非零仍然可以创建 nan / infinity

[记] C语言中的nan和inf

MATLAB中出现NAN怎么回事