这个问题的答案可能非常明显,但我无法通过粗略搜索在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_VALUE
和Infinity
之间“缓冲区”的解释是什么?
答案 0 :(得分:17)
...标准方式
在ECMAScript中,添加两个非零有限数作为 (ECMA-262§11.6.3“将加法运算符应用于数字”) :
使用 IEEE 754舍入到最接近模式计算总和并使用舍入到最接近的可表示值。如果幅度太大而无法表示,则操作溢出,结果是无穷大的适当符号。
IEEE-754的舍入到最近模式指定 (IEEE-7542008§4.3.1“舍入方向属性到最近”)
在以下两个舍入方向属性中,无限精确的结果,幅度至少 b emax ( b - ½ b 1- p )应转至∞,符号无变化;这里 emax 和 p 由目标格式决定(见3.3)。用:
- roundTiesToEven,最接近无限精确结果的浮点数;如果包含无法代表的无限精确结果的两个最近的浮点数同样接近,那么具有偶数最低位的数字应该被传递
- roundTiesToAway,最接近无限精确结果的浮点数应交付;如果包含无法代表的无限精确结果的两个最接近的浮点数同样接近,则应传递幅度较大的浮点数。
ECMAScript没有指定哪一轮到最近,但这里没关系,因为两者都给出了相同的结果。 ECMAScript中的数字是“double”,其中
因此结果必须至少为2 1024 - 2 970 ~1.797693134862315 8 ×10 308 in为了圆到无穷大。否则它只会舍入到MAX_VALUE,因为 比无穷大更接近。
请注意,MAX_VALUE = 2 1024 - 2 971 ,因此您需要添加至少2 971 - 2 970 < / sup> = 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 。 已经是无限的。
答案 1 :(得分:9)
如果查看Number.MAX_VALUE.toString(2)
,您会看到MAX_VALUE
的二进制表示为53个,后跟971个零。这是因为IEEE 754浮点由尾数系数乘以2的幂(因此浮点数的另一半是指数)。使用MAX_VALUE
时,尾数和指数都会被最大化,因此您会看到一堆位移了很多位。
简而言之,您需要增加MAX_VALUE
足以实际影响尾数,否则您的附加值会丢失并四舍五入。
Math.pow(2, 969)
是2的最低幂,不会将MAX_VALUE
提示为Infinity
。