# Number.MAX\_SAFE\_INTEGER

[JS](https://lochiwei.gitbook.io/web/js) ⟩ [value](https://lochiwei.gitbook.io/web/js/val) ⟩ [primitive](https://lochiwei.gitbook.io/web/js/val/prim) ⟩ [number](https://lochiwei.gitbook.io/web/js/val/prim/num) ⟩ [special](https://lochiwei.gitbook.io/web/js/val/prim/num/special) ⟩ Number.MAX\_SAFE\_INTEGER

{% hint style="info" %}
JS **可以表示的數字** (representable numbers) 與**數字之間的間隔**會根據不同的區間而有所區別：在 2⁰ \~ 2¹ 之間，數字的間隔是 2¯⁵²、在 2¹ \~ 2² 之間，數字的間隔是 2¯⁵¹，以此類推，每增加一個數量級，數字之間的**間隔**就會**乘以 2 倍**，到了  2⁵² \~ 2⁵³ 之間，數字的間隔是 2⁰ = 1，換句話說，到了這個區間以上，**只剩下整數可以表示**。

到了  2⁵³ \~ 2⁵⁴ 之間，數字的間隔是 2¹ = 2，換句話說，連整數都開始無法完整表示，開始有「漏洞」，這就是為什麼 [Number.MAX\_SAFE\_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) = **2⁵³ - 1** = 9007199254740991 的道理了。
{% endhint %}

{% tabs %}
{% tab title="MAX" %}

* replit - [JS: Number.MAX\_SAFE\_INTEGER](https://replit.com/@pegasusroe/JS-NumberMAXSAFEINTEGER#script.js)

```
    ┌─────────────────────────┐
    │ Number.MAX_SAFE_INTEGER │
    └─────────────────────────┘

       2⁵¹                                                2⁰
   2⁵²↴↓                                                  ↓
    = 11111111111111111111111111111111111111111111111111111
       ╰──────────────────── 52-bit ──────────────────────╯
    = 2⁵³ - 1
    = 9007199254740991
```

{% endtab %}

{% tab title="🗣 討論" %}

* [Why is Number.MAX\_SAFE\_INTEGER + 2.000000000000001 different than Number.MAX\_SAFE\_INTEGER + 2.0000000000000001?](https://stackoverflow.com/questions/69796073/javascript-why-is-number-max-safe-integer-2-000000000000001-different-than-nu)
  {% endtab %}
  {% endtabs %}

## 怪異的進位行為

```javascript
const N = Number.MAX_SAFE_INTEGER;        // 2⁵³ - 1

// 雖然我們知道 2⁵³ ~ 2⁵⁴ 之間，數字的間隔是 2¹ = 2，也就是都是「偶數」
// 但偶數的「跳法」卻頗為怪異：
N,      // 9007199254740991
N + 1,  // 9007199254740992
N + 2,  // 9007199254740992
N + 3,  // 9007199254740994
N + 4,  // 9007199254740996
N + 5,  // 9007199254740996
N + 6,  // 9007199254740996
N + 7,  // 9007199254740998
N + 8,  // 9007199254741000
```

雖然並不了解 IEEE 754 背後運作的原理，但下面我們試著「猜測」它是怎麼運作的：

```
let N = Number.MAX_SAFE_INTEGER = 9007199254740991

	N + 1 = 9007199254740992

	 ╭─────────────────── ☆ 52-digit ───────────────────╮
	11111111111111111111111111111111111111111111111111111
     +                                                      1
  ────────────────────────────────────────────────────────────
       100000000000000000000000000000000000000000000000000000
	╰─────────────────── ☆ 52-digit ───────────────────╯


	 N + 2 = 9007199254740992                           2¹
                                                            ⇩
	  ╭─────────────────── ☆ 52-digit ───────────────────╮
	 11111111111111111111111111111111111111111111111111111
     +                                                      10
   ────────────────────────────────────────────────────────────
        100000000000000000000000000000000000000000000000000001 (01 捨棄 1？)
	 ╰─────────────────── ☆ 52-digit ───────────────────╯
	 

	 N + 3 = 9007199254740994                           2¹
                                                            ⇩
	  ╭─────────────────── ☆ 52-digit ───────────────────╮
	 11111111111111111111111111111111111111111111111111111
     +                                                      11
    ────────────────────────────────────────────────────────────
        100000000000000000000000000000000000000000000000000010
	 ╰─────────────────── ☆ 52-digit ───────────────────╯
	 

	 N + 4 = 9007199254740996                           2¹
                                                            ⇩
	  ╭─────────────────── ☆ 52-digit ───────────────────╮
	 11111111111111111111111111111111111111111111111111111
     +                                                     100
   ────────────────────────────────────────────────────────────
        100000000000000000000000000000000000000000000000000011 (11 進位？)
      = 10000000000000000000000000000000000000000000000000010
	 ╰─────────────────── ☆ 52-digit ───────────────────╯
	 

	 N + 5 = 9007199254740996                           2¹
                                                            ⇩
	  ╭─────────────────── ☆ 52-digit ───────────────────╮
	 11111111111111111111111111111111111111111111111111111
      +                                                    101
   ────────────────────────────────────────────────────────────
        100000000000000000000000000000000000000000000000000100
	 ╰─────────────────── ☆ 52-digit ───────────────────╯
	 

	 N + 6 = 9007199254740996                           2¹
                                                            ⇩
	  ╭─────────────────── ☆ 52-digit ───────────────────╮
	 11111111111111111111111111111111111111111111111111111
      +                                                    110
   ────────────────────────────────────────────────────────────
        100000000000000000000000000000000000000000000000000101 (01 捨棄 1？)
	 ╰─────────────────── ☆ 52-digit ───────────────────╯
	 

	 N + 7 = 9007199254740998                           2¹
                                                            ⇩
	  ╭─────────────────── ☆ 52-digit ───────────────────╮
	 11111111111111111111111111111111111111111111111111111
      +                                                    111
   ────────────────────────────────────────────────────────────
        100000000000000000000000000000000000000000000000000110
	 ╰─────────────────── ☆ 52-digit ───────────────────╯
	 

	 N + 8 = 9007199254741000                           2¹
                                                            ⇩
	  ╭─────────────────── ☆ 52-digit ───────────────────╮
	 11111111111111111111111111111111111111111111111111111
      +                                                   1000
   ────────────────────────────────────────────────────────────
        100000000000000000000000000000000000000000000000000111 (11 進位？)
      = 10000000000000000000000000000000000000000000000000100
	 ╰─────────────────── ☆ 52-digit ───────────────────╯

```
