在JavaScript中,为什么0除以0会返回NaN,而其他任何数除以0都会返回无穷大?

64

我觉得这段代码

console.log(1 / 0)

应该返回NaN,但实际上它返回了Infinity。然而,这段代码:

console.log(0 / 0)

does返回NaN。有人能帮我理解这种功能的原因吗?它不仅似乎不一致,而且在x / 0的情况下似乎是错误的,其中x!== 0


1
https://dev59.com/PXA75IYBdhLWcg3wlqIT - PSL
1
这里有一个不错的教程:http://javascript.info/tutorial/number-math。 - user1864610
2
任何数字中都有无限个零,所以 x / 0 === Infinity 对我来说是合理的。 - Ken Herbert
4个回答

43

12

除了基于零的数学概念的答案外,浮点数还有特殊考虑。每个下溢结果,即任何绝对值过小而无法表示为非零数字的非零数字,都表示为零。

0/0可能真的是1e-500/1e-600、1e-600/1e-500或许多其他非常小的值的比值。

实际比率可以是任何值,因此没有意义的数字答案,结果应为NaN。

现在考虑1/0。无论0表示1e-500还是1e-600都没有关系。无论如何,除法都会溢出,正确的结果是用于表示溢出的值Infinity。


在这里语言非常重要。小数不表示为零,零也不表示小数。这种措辞会导致人们对浮点数近似值的错误理解。浮点除法可能会返回零,对于其数学结果非常微小的操作,但这是因为浮点除法被定义为返回最接近精确值的可表示值,而不是因为它被定义为近似表示商。每个浮点值仅代表一个数字,而不是一个区间。 - Eric Postpischil
1
@EricPostpischil 是的和不是。是的,IEEE 754浮点算术是明确定义的,每个计算都有一个确定的结果,并且每个有限数字都有一个单一值。但是,如果孤立地看这个系统,它将是无用的。它之所以实用,是因为它能够在许多情况下产生对科学或工程计算结果的良好近似,而这些计算实际上是基于实数算术定义的。我会考虑如何重新措辞我的答案,以正确区分实数算术和浮点算术。 - Patricia Shanahan
@PatriciaShanahan: 我喜欢的想法是,浮点值表示将来会被视为精确数字的东西,但在许多情况下,它将表示其精确数值结果在前进时超出 1/2ulp。如果 abc 相互接近,并且想要显示四个有效数字的总和,则知道 a+b+c 的值将在正确值的百万分之一范围内(实际精度实际上更好)可能比精确的误差术语更有帮助。 - supercat

5

我知道这已经是老话题了,但我认为需要指出的是,在JS中还有一个-0,它与0+0有所不同,这使得JS的这个特性比一开始看起来更加合理。

1 / 0 -> Infinity
1 / -0 -> -Infinity 

这在逻辑上是有意义的,因为在微积分中,除以0的原因是未定义的,仅仅是因为左极限趋向于负无穷大,右极限趋向于正无穷大。由于在JS中,-00是不同的对象,所以将正0应用于正无穷大的求值,将负0应用于负无穷大的求值是有意义的。

这种逻辑不适用于0/0,它是不确定的。与1/0不同,我们可以通过这种方法得到两个结果来计算0/0

lim h->0(0/h) = 0
lim h->0(h/0) = Infinity

这显然是不一致的,因此结果为NaN


有趣,但不完整。想一下 lim h -> 0 (h / h)。由于JS具有正零和负零,因此应该存在正负极限。因此,只有0/-0和-0/0应导致NaN。其他应为正无穷或负无穷。当然,我内心的数学家仍像婴儿一样哭泣。 - SMBiggs
@SMBiggs,为什么是 lim h -> 0 (h / h) 而不是 lim h -> 0 (2h / h)(例如)?这样做没有一致的结果。 - trincot
在评论部分,我没有足够的空间来包含产生相同结果的无限变化。相反,我使用了我能想到的创建所讨论形状(和极限)图形的最简单形式。 - SMBiggs

1
在数学中,除法可以被看作是乘法的逆运算。当你用一个数a除以另一个数b时,实际上是在试图找出b可以整除a多少次。然而,当你尝试除以零时,你在问零可以整除数a多少次。由于零没有值,它不能用来衡量它可以整除任何数的次数。这种情况在数学中创建了一个未定义或不确定的状态。
然而,在JavaScript和IEEE 754浮点标准的背景下,对零的除法处理方式不同。当你将一个正数(例如1)除以零时,结果是无穷大。这是因为根据IEEE 754标准,数系统被扩展为包括正无穷和负无穷,从而允许计算极限。
想象一下:当除数趋近于零时,除法的结果会变得越来越大而无限。换句话说,结果趋近于无穷大。这就是为什么在JavaScript(以及其他遵循IEEE 754标准的编程语言)中,正数除以零的结果是无穷大。

这并没有回答问题。一旦你拥有足够的声望,你就可以评论任何帖子;相反,提供不需要提问者澄清的答案。- 来自审查 - Muhammad Khuzaima Umair
1
你明白我的回答吗? - arsi
是的,我已经仔细阅读并理解了。答案只是解释了为什么除以零会得到“无穷大”,但没有解释为什么“0/0”是“NaN”以及为什么存在这种差异。 - Muhammad Khuzaima Umair
就这样想吧,在数学中,0/0没有合理的解释和有意义的数值答案。这种行为是由IEEE 754浮点标准定义的,并在各种编程语言(包括JavaScript)和平台上一致实现。 - arsi
你应该在回答中也包括这一点。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接