# 一个数字可以在不损失精度的情况下达到的JavaScript的最高整数值是多少？

2020/09/19 06:31 · javascript ·  · 0评论

JavaScript有两种数字类型：`Number``BigInt`

• 2 53 -1，或
• +/- 9,007,199,254,740,991，或
• 九四十亿七千七百亿一百九十二亿一千二百四十五万四十九万一千九百一十一

``````const log = console.log
var x = 9007199254740992
var y = -x
log(x == x + 1) // true !
log(y == y - 1) // also true !

// Arithmetic operators work, but bitwise/shifts only operate on int32:
log(x / 2)      // 4503599627370496
log(x >> 1)     // 0
log(x | 1)      // 1``````

> = ES6：

``````Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;``````

<= ES5

``````Number.MAX_VALUE;
Number.MIN_VALUE;``````

``````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
}``````

``````(Infinity>100)
=> true

// Also worth noting
Infinity - 1 == Infinity
=> true

Math.pow(2,1024) === Infinity
=> true``````

Jimmy的答案正确地将连续的JavaScript整数频谱表示为-90071992547409929007199254740992（包括9007199254740993（对不起9007199254740993，您可能会认为您是9007199254740993，但您错了！
jsfiddle中或以下的演示）。

``console.log(9007199254740993);``

``````/**
* 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 numMinusOne = number - 1;
var numPlusOne = number + 1;

return ((number - numMinusOne) === 1) && ((number - numPlusOne) === -1);
}

//Find the highest number

//Get a number higher than the valid integer range
highestNumber *= 2;
}

//Find the lowest number you can't add/subtract 1 from
var numToSubtract = highestNumber / 4;
while (numToSubtract >= 1) {
highestNumber = highestNumber - numToSubtract;
}

numToSubtract /= 2;
}

//And there was much rejoicing.  Yay.
console.log('HighestNumber = ' + highestNumber);``````

# 为了安全起见

``var MAX_INT = 4294967295;``

# 推理

• 您的大多数循环都不会运行28.56年
• `9007199254740992 === Math.pow(2, 53) + 1` 足够证明
• 您应该坚持`4294967295`这样`Math.pow(2,32) - 1`做，以免发生移位的预期问题

``````(function () {
"use strict";

var x = 0
, start = new Date().valueOf()
;

while (x + 1 != x) {
if (!(x % 10000000)) {
console.log(x);
}

x += 1
}

console.log(x, new Date().valueOf() - start);
}());``````

（碰巧将按位运算符和数组的最大长度限制为32位整数。）

ECMAScript 6：

``````Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;``````

``````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``````

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

``````  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. ``````

``````  |--> This bit is implicit and persistent.
|
1 . 1111 ---- 1111  *  2^52      =>  1  1111 ---- 1111.
|-- 52 bits --|                     |-- 52 bits --|

(+1)
(radix point has no way to go)
1 . 0000 ---- 0000  *  2^52 * 2  =>  1  0000 ---- 0000. * 2
|-- 52 bits --|                     |-- 52 bits --|

=>  1 . 0000 ---- 0000  *  2^53
|-- 52 bits --| ``````

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

``````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``````

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

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

``````input: 2251799813685246.75   output: 2251799813685246.8  // expected: 2251799813685246.75
input: 2251799813685246.25   output: 2251799813685246.2  // expected: 2251799813685246.25
input: 2251799813685246.5    output: 2251799813685246.5

// If the digits exceed 17, JavaScript round it to print it.
//, but the value is 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"``````

[！[在此处输入图片描述] [1]] [1]

``````for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);``````

``maxInt = -1 >>> 1``

``var a = 123456789012345678901012345678901n;``

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

...但是有效。

``javascript: alert(9e15-(9e15+1));``

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

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

# 让我们来看看资源

## 描述

`MAX_SAFE_INTEGER`常数的值为`9007199254740991`（9,007,199,254,740,991或〜9万亿）。后面这个数字的原因是JavaScript使用双精度浮点数号中规定IEEE 754，只能安全地之间代表数字`-(2^53 - 1)``2^53 - 1`

## 浏览器兼容性

Firefox 3似乎没有大量问题。

1e + 200 * 1e + 100将计算为1e + 300。

Safari似乎也没有问题。（作为记录，如果有其他人决定对此进行测试，则它在Mac上。）

``Number.MAX_VALUE = 1.7976931348623157e+308``