添加到Number.MAX_VALUE

这个问题的答案可能是很明显的,但我无法在Mozilla文档中find它,也不能在粗略的search中find它。

如果你有这样的代码

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“舍入方向属性到最近”)

在以下两个舍入方向属性中,幅度至less为b emaxb – 1/2 b 1 – p的无限精确的结果将圆整到∞ ,符号不变; 这里emaxp由目标格式确定(见3.3)。 附:

  • roundTiesToEven, 最接近无限精确结果的浮点数应交付 ; 如果包含无法表示的无限精确的结果的两个最接近的浮点数相等,则具有最低有效数字的浮点数将被递送
  • roundTiesToAway,则将传递最接近无限精确结果的浮点数; 如果包含无法表示的无限精确结果的两个最接近的浮点数同样接近,那么将传送具有较大幅度的浮点数。

ECMAScript没有指定哪一个圆到最近,但在这里没有关系,因为两者都给出相同的结果。 ECMAScript中的数字是“double”,其中

  • b = 2
  • emax = 1023
  • p = 53,

所以结果必须至less为2 1024 – 2 970〜1.797693134862315 8 ×10 308才能圆到无限。 否则,它会绕到MAX_VALUE,因为这比无限大。

注意,MAX_VALUE = 2 1024 – 2 971 ,所以你至less需要添加2 971 – 2 970 = 2 970〜9.979202×10 291才能获得无穷大。 我们可以检查:

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

同时,你的Math.pow(100,1000) 〜2 6643.9远远超过2 1024 – 2 970 。 这已经无限的了。

如果您查看Number.MAX_VALUE.toString(2) ,您会看到MAX_VALUE的二进制表示forms是53个,其后是971个零。 这是因为IEEE 754浮点是由尾数系数乘以2的幂(因此浮点数的另一半是指数 )构成的。 用MAX_VALUE ,尾数和指数都是最大的,所以你看到一堆的位移了很多。

总之,您需要增加MAX_VALUE才能真正影响尾数,否则您的附加值会丢失并舍去。

Math.pow(2, 969)Math.pow(2, 969)的最低次幂,不会使MAX_VALUE变成Infinity