这个问题的答案可能很痛苦,但我无法从Mozilla文档或Google的粗略搜索中找到答案。

如果您有这样的代码

Number.MAX_VALUE + 1; // Infinity, right?
Number.MIN_VALUE - 1; // -Infinity, right?


然后,我希望将任何内容添加到Number.MAX_VALUE会将其推到Infinity。结果就是Number.MAX_VALUE吐口水又回到我身边。

但是,当在Chrome JS控制台中玩耍时,我注意到在添加/减去足够多之前,它实际上并没有变成Infinity

Number.MAX_VALUE + Math.pow(100,1000); // now we hit Infinity
Number.MIN_VALUE - Math.pow(100,1000); // -Infinity at last


Number.MAX_VALUEInfinity之间的“缓冲区”的解释是什么?

最佳答案

标准地...

在ECMAScript中,两个非零有限数字的加法实现为(ECMA-262§11.6.3“将加法运算符应用于数字”):


  使用IEEE 754四舍五入模式计算总和并将其四舍五入为最接近的可表示值。如果幅度太大而无法表示,则操作会溢出,结果将是无穷大的适当符号。


IEEE-754的最近舍入模式指定(IEEE-754 2008§4.3.1“最接近的环绕方向属性”)


  在以下两个取整方向属性中,大小至少为bemax(b-½b1-p)的无限精确结果应取整为∞且符号不变。这里的emax和p由目标格式决定(请参见3.3)。带有:
  
  
  roundTiesToEven,应传递最接近无限精确结果的浮点数;如果括号中代表无穷无穷精确结果的两个最接近的浮点数相等,则应交付一个具有甚至最低有效位的数字
  roundTiesToAway,应交付最接近无限精确结果的浮点数;如果包围无可表示的无限精确结果的两个最接近的浮点数相等地接近,则应传递幅度更大的那个。
  


ECMAScript没有指定最近舍入中的哪一个,但是在这里并不重要,因为两者都给出相同的结果。 ECMAScript中的数字为“双”,其中


b = 2
emax = 1023
p = 53


因此,结果必须至少为21024-2970〜1.7976931348623158×10308,才能四舍五入为无穷大。否则,它将四舍五入到MAX_VALUE,因为这比Infinity还要近。

请注意,MAX_VALUE = 21024-2971,因此您需要至少添加2971-2970 = 2970〜9.979202×10291才能获得无穷大。我们可以检查:

>>> Number.MAX_VALUE + 9.979201e291
1.7976931348623157e+308
>>> Number.MAX_VALUE + 9.979202e291
Infinity




同时,您的Math.pow(100,1000)〜26643.9远远超出了21024-2970。它已经是无穷大。

10-06 00:08