这是由语言定义的吗?有确定的最大值吗?在不同的浏览器中是否有所不同?


当前回答

253 == 9 007 199 254 740 992。这是因为数字存储为52位尾数中的浮点数。

最小值为-253。

这使得一些有趣的事情发生了

Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true

也可能是危险的:)

var MAX_INT = Math.pow(2, 53); // 9 007 199 254 740 992
for (var i = MAX_INT; i < MAX_INT + 2; ++i) {
    // infinite loop
}

进一步阅读:http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html

其他回答

Jimmy的答案正确地表示了连续的JavaScript整数谱,从-9007199254740992到9007199254740992,包括(对不起,9007199254740993,您可能认为您是9007199254740993,但您错了! 下面或jsfiddle中的演示)。

console.log(9007199254740993);

然而,没有答案可以通过编程来发现/证明这一点(除了CoolAJ86在他的回答中提到的将在28.56年完成的答案),所以这里有一个稍微更有效的方法来做到这一点(准确地说,它更有效约28.559999999968312年:),以及一个测试小提琴:

/** * Checks if adding/subtracting one to/from a number yields the correct result. * * @param number The number to test * @return true if you can add/subtract 1, false otherwise. */ var canAddSubtractOneFromNumber = function(number) { var numMinusOne = number - 1; var numPlusOne = number + 1; return ((number - numMinusOne) === 1) && ((number - numPlusOne) === -1); } //Find the highest number var highestNumber = 3; //Start with an integer 1 or higher //Get a number higher than the valid integer range while (canAddSubtractOneFromNumber(highestNumber)) { highestNumber *= 2; } //Find the lowest number you can't add/subtract 1 from var numToSubtract = highestNumber / 4; while (numToSubtract >= 1) { while (!canAddSubtractOneFromNumber(highestNumber - numToSubtract)) { highestNumber = highestNumber - numToSubtract; } numToSubtract /= 2; } //And there was much rejoicing. Yay. console.log('HighestNumber = ' + highestNumber);

许多先前的答案显示9007199254740992 === 9007199254740992 + 1为真,以验证9,007,199,254,740,991是最大且安全的整数。

但如果我们继续积累:

input: 9007199254740992 + 1  output: 9007199254740992  // expected: 9007199254740993
input: 9007199254740992 + 2  output: 9007199254740994  // expected: 9007199254740994
input: 9007199254740992 + 3  output: 9007199254740996  // expected: 9007199254740995
input: 9007199254740992 + 4  output: 9007199254740996  // expected: 9007199254740996

我们可以看到,在大于9,007,199,254,740,992的数字中,只有偶数是可表示的。

这是一个解释双精度64位二进制格式如何工作的条目。让我们看看如何使用这种二进制格式保存(表示)9,007,199,254,740,992。

使用一个简短的版本从4,503,599,627,370,496演示:

  1 . 0000 ---- 0000  *  2^52            =>  1  0000 ---- 0000.  
     |-- 52 bits --|    |exponent part|        |-- 52 bits --|

在箭头的左边,我们有位值1和一个相邻的基数点。通过消耗左边的指数部分,基数点向右移动52步。基数点在最后,我们得到纯二进制的4503599627370496。

现在,让我们继续将分数部分加1,直到所有的位都设置为1,这等于十进制的9,007,199,254,740,991。

  1 . 0000 ---- 0000  *  2^52  =>  1  0000 ---- 0000.  
                       (+1)
  1 . 0000 ---- 0001  *  2^52  =>  1  0000 ---- 0001.  
                       (+1)
  1 . 0000 ---- 0010  *  2^52  =>  1  0000 ---- 0010.  
                       (+1)
                        . 
                        .
                        .
  1 . 1111 ---- 1111  *  2^52  =>  1  1111 ---- 1111. 

因为64位双精度格式严格地为分数部分分配了52位,如果我们添加另一个1,就没有更多的位可用了,所以我们可以做的是将所有位设置为0,并操作指数部分:

  ┏━━▶ This bit is implicit and persistent.
  ┃        
  1 . 1111 ---- 1111  *  2^52      =>  1  1111 ---- 1111. 
     |-- 52 bits --|                     |-- 52 bits --|

                          (+1)

  1 . 0000 ---- 0000  *  2^52 * 2  =>  1  0000 ---- 0000. * 2  
     |-- 52 bits --|                     |-- 52 bits --|
                                      (By consuming the 2^52, radix
                                       point has no way to go, but
                                       there is still one 2 left in
                                       exponent part)
  =>  1 . 0000 ---- 0000  *  2^53 
         |-- 52 bits --| 

现在我们得到9,007,199,254,740,992,对于比它更大的数,格式只能处理2的增量,因为分数部分的每一个增量1最终都会在指数部分乘以左边的2。这就是为什么双精度64位二进制格式不能保存大于9,007,199,254,740,992的奇数:

                            (consume 2^52 to move radix point to the end)
  1 . 0000 ---- 0001  *  2^53  =>  1  0000 ---- 0001.  *  2
     |-- 52 bits --|                 |-- 52 bits --|

按照这种模式,当数字大于9,007,199,254,740,992 * 2 = 18,014,398,509,481,984时,只能保持4倍的分数:

input: 18014398509481984 + 1  output: 18014398509481984  // expected: 18014398509481985
input: 18014398509481984 + 2  output: 18014398509481984  // expected: 18014398509481986
input: 18014398509481984 + 3  output: 18014398509481984  // expected: 18014398509481987
input: 18014398509481984 + 4  output: 18014398509481988  // expected: 18014398509481988

那么[2 251 799 813 685 248,4 503 599 627 370 496)之间的号码呢?

 1 . 0000 ---- 0001  *  2^51  =>  1 0000 ---- 000.1
     |-- 52 bits --|                |-- 52 bits  --|

0.1的二进制值正好是2^-1 (=1/2)(=0.5) 因此,当数字小于4,503,599,627,370,496(2^52)时,有一位可用来表示整数的1/2倍:

input: 4503599627370495.5   output: 4503599627370495.5  
input: 4503599627370495.75  output: 4503599627370495.5  
            

小于2,251,799,813,685,248 (2^51)

input: 2251799813685246.75   output: 2251799813685246.8  // expected: 2251799813685246.75 
input: 2251799813685246.25   output: 2251799813685246.2  // expected: 2251799813685246.25 
input: 2251799813685246.5    output: 2251799813685246.5
/**
   Please note that if you try this yourself and, say, log 
   these numbers to the console, they will get rounded. JavaScript
   rounds if the number of digits exceed 17. The value 
   is internally held correctly:
*/
            
input: 2251799813685246.25.toString(2) 
output: "111111111111111111111111111111111111111111111111110.01"
input: 2251799813685246.75.toString(2) 
output: "111111111111111111111111111111111111111111111111110.11"
input: 2251799813685246.78.toString(2)   
output: "111111111111111111111111111111111111111111111111110.11"

指数部分的取值范围是多少?格式为它分配了11位。

来自维基百科(欲了解更多细节,请访问那里)

为了使指数部分等于2^52,我们需要令e = 1075。

JavaScript在ECMAScript 2020中收到了一个新的数据类型:BigInt。它引入了带有“n”后缀的数值字面量,并允许任意精度:

var a = 123456789012345678901012345678901n;

当然,当这样大的整数(可能是无意的)被强制转换为数字数据类型时,精度仍然会丢失。

而且,很明显,由于有限的内存,总是会有精度限制,为了分配必要的内存和对如此大的数字执行算术,在时间方面会有成本。

例如,生成一个具有10万个十进制数字的数字,在完成之前会有明显的延迟:

console.log(BigInt("1".padEnd(100000,"0")) + 1n)

...但它确实有效。

我这样写:

var max_int = 0x20000000000000;
var min_int = -0x20000000000000;
(max_int + 1) === 0x20000000000000;  //true
(max_int - 1) < 0x20000000000000;    //true

int32也是一样

var max_int32 =  0x80000000;
var min_int32 = -0x80000000;

>= ES6:

Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;

< = ES5

参考文献:

Number.MAX_VALUE;
Number.MIN_VALUE;

console.log (MIN_VALUE, Number.MIN_VALUE); console.log (MAX_VALUE, Number.MAX_VALUE); console.log (MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);/ / ES6 console.log (MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);/ / ES6