添加到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_VALUE
和Infinity
之间的“缓冲区”是什么?
标准方式…
在ECMAScript中,两个非零有限数的添加被实现为(ECMA-262§11.6.3“将附加运算符应用于数字”) :
计算总和并使用IEEE 754轮到模式将其舍入到最接近的可表示值。 如果幅度太大而不能表示,则操作溢出,结果是无限的适当的符号。
IEEE-754的最近邻模式规定(IEEE-754 2008§4.3.1“舍入方向属性到最近”)
在以下两个舍入方向属性中,幅度至less为b emax ( b – 1/2 b 1 – p )的无限精确的结果将圆整到∞ ,符号不变; 这里emax和p由目标格式确定(见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
。