上一篇我們認識了什麼是資料值(Value),也知道每個值都有自己的資料型態。
從這篇開始,我們要逐一認識 JavaScript 中不同的資料型態。
第一個登場的,就是最直覺的——數字型態(Number)。
這篇文章會帶你了解:數字值怎麼寫、JavaScript 怎麼儲存數字、以及為什麼小數計算有時候會「不太準」。
JavaScript 中的數字怎麼寫?
像 13、9.81、-5,這些你在數學裡看到的數字,在 JavaScript 裡都屬於數字型態。
在程式碼裡,你只要直接把數字寫出來就好:
13當 JavaScript 執行到這行,它就會把 13 轉換成位元,儲存在記憶體裡。
如果要寫小數,就加上小數點:
9.81如果要表示非常大或非常小的數字,還可以用科學記號法。
寫法是在數字後面加上 e,再接一個數字,代表「乘以 10 的幾次方」:
2.998e8這代表的就是 2.998 × 10⁸,也就是 299,800,000。
JavaScript 用 64 位元儲存數字,這代表什麼?
前面提到,當你在程式碼裡寫下 13,JavaScript 會把它轉換成位元存進記憶體。
這裡的 13 就是一個數字值——也就是一個資料型態為「數字」的資料值。
那 JavaScript 會用多少位元來存這個數字值呢?
答案是固定的:64 個位元。
不管你寫的是 1、9999、還是 3.14,JavaScript 一律用 64 個位元來儲存。
你可以把它想像成一排有 64 格的格子,每一格只能填 0 或 1:
[0][1][0][0][1][1][0][1] ... 一共 64 格JavaScript 就是靠這 64 格裡 0 和 1 的排列組合,來表示不同的數字。
64 個位元能表示多少種數字?
那 64 格能排出多少種組合呢?
用十進位來想比較好理解:如果你有 2 位數,每一位可以填 0 到 9,就能表示 10² = 100 種數字(0 到 99)。
同樣的道理,64 個位元,每一格可以填 0 或 1,就能表示 2⁶⁴ 種組合。
2⁶⁴ 大約是 18,000,000,000,000,000,000——也就是 18 後面再接 18 個零。
這是一個非常大的數字。
也就是說,光靠 64 個位元的排列組合,JavaScript 就能表示超過 18 百京種不同的數字值。
什麼是溢位(Overflow)?
在早期的電腦裡,記憶體非常有限,程式常常只用 8 個位元或 16 個位元來儲存一個數字。
8 個位元最多只能表示 2⁸ = 256 種數字,範圍非常小。
如果計算的結果超出了這個範圍,就會發生溢位(Overflow)——也就是數字「塞不進去」,程式得到一個錯誤的結果。
而現在 JavaScript 用 64 位元,能表示的範圍大到日常使用幾乎不會碰到溢位的問題。
只有在處理天文數字等級的計算時,才需要特別留意。
18 百京種組合,實際上不是全部都能用
不過,能組合出 18 百京種數字值,不代表你能表示 0 到 18 百京之間的所有數字。
因為這些組合還要分給其他用途。
第一,負數也要佔名額。
如果 64 個位元全部拿來排列組合,只能表示正數(像是 0、1、2、3……)。
但我們也需要負數啊,像 -5、-100 這些。
所以 JavaScript 會拿其中 1 個位元出來,專門記錄「這個數字是正的還是負的」——0 代表正數,1 代表負數。
這樣一來,能用來表示數字大小的位元就從 64 個變成 63 個,可表示的數字種類就少了一半。
第二,小數也要佔名額。
像 9.81 這種有小數點的數字,JavaScript 需要知道「小數點在哪裡」。
所以它會再拿一部分的位元出來,專門記錄小數點的位置。
這些位元也不能拿來表示數字大小了,所以能表示的數字種類又再變少。
正數、負數、小數全部分完之後,JavaScript 實際上能精確表示的最大整數大約是 9,000,000,000,000,000(9 後面 15 個零)。
這個數字依然非常大,日常使用完全夠用。
為什麼小數計算有時候會「不太準」?
這是很多初學者會碰到的疑惑。
你可能會預期 0.1 + 0.2 等於 0.3,但在 JavaScript 裡:
0.1 + 0.2 // 得到 0.30000000000000004為什麼會這樣?
因為 JavaScript 只有 64 個位元可以用來儲存一個數字,而有些小數在二進位裡是「除不盡」的。
這就像十進位裡的 1/3 = 0.33333… 一樣,永遠寫不完。
當 JavaScript 用有限的位元去存一個「除不盡」的小數時,就只能存一個非常接近、但不完全精確的近似值。
整數的計算就沒有這個問題——只要數字在 9,000,000,000,000,000 以內,結果都會是精確的。
所以重點是:把小數視為近似值,而不是精確值。
在大多數情況下,這個微小的誤差不會影響你的程式,但知道這件事很重要,這樣碰到的時候就不會覺得奇怪了。
小結
讓我們整理一下這篇文章的重點:
- JavaScript 的數字值可以用整數、小數、科學記號法來表示。
- 每個數字值固定佔用 64 個位元的記憶體空間。
- 64 位元裡,有一部分要用來記錄正負號和小數點位置,所以能精確表示的最大整數大約是 9,000,000,000,000,000。
- 早期電腦因為位元數少,容易發生溢位;現在用 64 位元,日常使用不太需要擔心。
- 小數計算可能會有微小的誤差,因為有些小數在二進位裡除不盡,只能存近似值。