Ash*_*bhu 6 javascript numbers
在处理JavaScript数字时,我发现了以下奇怪的行为.
var baseNum = Math.pow(2, 53);
console.log(baseNum); //prints 9007199254740992
console.log(baseNum + 1); //prints 9007199254740992 again!
console.log(baseNum + 2); //prints 9007199254740994, 2 more than +1
console.log(baseNum + 3) // prints 9007199254740996, 2 more than +2
console.log(baseNum + 4) // prints 9007199254740996, same as +3
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?我知道JavaScript只能代表数字2^53(它们内部是'双'?),但为什么会出现这种情况呢?
如果2^53是实际最大值,那么为什么我们有Number.MAX_VALUE(1.7976931348623157e+308)?
Cra*_*sta 10
这个数字确实是一个双倍.尾数有52位(关于双精度的源和额外信息).因此,从一位存储2 ^ 53个剁.
使用3个符号位(相当直接)和另外两个部分(尾数M和指数E)存储该数字.该数字计算如下:
(1 + M/2 ^ 53)*2 ^(E-1023)
我可能会有一些细节,但基本的想法就在那里.因此当数字是2 ^ 53,2 ^(E-1023)= 2 ^ 53并且因为M中只有52位,所以你不能再代表最低位.
@CrazyCasta给出的答案很好.
唯一要补充的是你的第二个问题:
如果
2^53是实际最大值,那么为什么我们有Number.MAX_VALUE(1.7976931348623157e+308)?
正如您所演示的那样,它可以存储大于2^53,但精度更差的数字2^0.随着数字越来越大,它们失去了越来越多的精确度.
因此,最大值Number.MAX_VALUE意味着它可以代表的"最大"值; 但这并不意味着准确度与接近2^1或的值相同2^53.
对此的推论是Number可以包含Number.MIN_VALUE的最小值 ; 不是最消极的.也就是说,它是最接近零的非零数字:( 5.00E-324注意这是一个正数!).