简体   繁体   English

奇怪的JavaScript编号行为

[英]Strange JavaScript Number behavior

I found the following weird behavior while working on 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

What is happening here? 这里发生了什么? I understand that JavaScript can only represent numbers upto 2^53 (they are internally 'double'?), but why this behavior? 我理解JavaScript只能代表高达2^53数字(它们内部是'双'?),但为什么会出现这种情况呢?

If 2^53 is the practical max, then why do we have Number.MAX_VALUE ( 1.7976931348623157e+308 )?. 如果2^53是实际最大值,那么为什么我们有Number.MAX_VALUE1.7976931348623157e+308 )?

The number is really a double. 这个数字确实是一个双倍。 The mantissa has 52-bits ( source and extra information on doubles ). 尾数有52位( 关于双精度的源和额外信息 )。 Therefore, storing 2^53 chops off the one bit. 因此,从一位存储2 ^ 53个剁。

The number is stored using 3 pieces a sign bit (fairly straight forward) and two other pieces, the mantissa M and the exponent E. The number is calculated as: 使用3个符号位(相当直接)和另外两个部分(尾数M和指数E)存储该数字。该数字计算如下:

(1 + M/2^53) * 2^(E-1023) (1 + M / 2 ^ 53)* 2 ^(E-1023)

I might have some of the specifics there a little off, but the basic idea is there. 我可能会有一些细节,但基本的想法就在那里。 So when the number is 2^53, 2^(E-1023) = 2^53 and since there are only 52 bits in M, you can no longer represent the lowest bit. 因此当数字是2 ^ 53,2 ^(E-1023)= 2 ^ 53并且因为M中只有52位,所以你不能再代表最低位。

The answer that @CrazyCasta gave is good. @CrazyCasta给出的答案很好。

The only thing to add is to your second question: 唯一要补充的是你的第二个问题:

If 2^53 is the practical max, then why do we have Number.MAX_VALUE ( 1.7976931348623157e+308 )? 如果2^53是实际最大值,那么为什么我们有Number.MAX_VALUE1.7976931348623157e+308 )?

As you've demonstrated, it can store numbers larger than 2^53 , but with precision worse than 2^0 . 如您所示,它可以存储大于2^53数字,但精度低于2^0 As the numbers grow ever larger, they lose more and more precision. 随着数字越来越大,它们失去了越来越多的精确度。

So max value in Number.MAX_VALUE means the "largest" value it can represent; 因此, Number.MAX_VALUE中的Number.MAX_VALUE表示它可以表示的“最大”值; but it doesn't mean that accuracy is the same as a value near 2^1 or 2^53 . 但这并不意味着准确度与2^12^53附近的值相同。

A corollary to this is that Number.MIN_VALUE is the smallest value that Number can contain; 对此的推论是Number.MIN_VALUE是Number可以包含的最小值 ; not the most negative . 不是最消极的 That is, it is the closest non-zero number to zero: 5.00E-324 (notice that's a positive number!). 也就是说,它是最接近零的非零数字: 5.00E-324 (注意这是一个正数!)。

The maximum value storable in a long is much larger than the maximum value storable with exact precision in a long. 长度可存储的最大值远大于可存储的最大值,精确度可长。 Floating-point numbers have a fixed maximum number of significant digits, but the magnitude of the number can get much larger. 浮点数具有固定的最大有效位数,但数字的大小可以变得更大。

There are a certain number of bits allocated for an exponent (power of two), and that's implicitly multiplied by the mantissa stored in the rest of the bits. 为指数分配了一定数量的比特(2的幂),并且隐含地乘以存储在其余比特中的尾数。 Beyond a certain point, you lose precision, but you can keep incrementing the exponent to represent larger and larger magnitudes. 超过某一点,你会失去精确度,但你可以继续递增指数来表示更大和更大的数量级。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM