16.6 估計 2 的次方有多大
二進制不只藏在進制轉換題裡——整數型態的範圍全是 2 的次方。這一節教你一套「秒估 2^n 量級」的功夫,之後判斷「這個數塞不塞得下 int」「陣列開這麼大會不會 MLE」全靠它。
先把小的背熟(2^0 \sim 2^{10},唸幾遍就記得):
核心近似只有一條:
要估 2 的大次方,把指數拆成「10 的倍數+零頭」,套國二的指數律(同底數相乘、指數相加):
實際的 2^{31} = 2147483648,估得相當準。整理成速查表:
| 2 的次方 | 估計 | 實際值 | 口訣 |
|---|---|---|---|
| 2^{10} | \approx 10^3 | 1024 | 千 |
| 2^{20} | \approx 10^6 | 1048576 | 百萬 |
| 2^{30} | \approx 10^9 | 1073741824 | 十億 |
| 2^{31} - 1 | \approx 2 \times 10^9 | 2147483647 | int 上限 |
| 2^{53} | \approx 8 \times 10^{15} | 9007199254740992 | double 精確整數門檻(9.6) |
| 2^{63} - 1 | \approx 8 \times 10^{18} | 9223372036854775807 | long long 上限 |
(估出來會略偏小:每次把 1024 當 1000 少算了 2.4\%,次方越高累積越多——2^{63} 估 8 \times 10^{18}、實際 9.2 \times 10^{18}。做量級判斷完全夠用。)
¶解開上冊 2.3 的神祕數字
int 的上限為什麼是 2147483647 這個怪數?現在你有齊所有拼圖了:int 佔 32 個位元(2.2),每個位元是一個二進制位;其中 1 個用來區分正負,剩下 31 個裝數值——而 16.1 說過,n 個二進制位最多數到 2^n - 1。所以:
long long 同理:64 位元留 63 個裝數值,上限 2^{63} - 1 \approx 9.2 \times 10^{18}。驗證一下 2^{31}(用連乘,9.8 說過整數次方別用 pow):
#include <iostream>
using namespace std;
int main() {
long long p = 1;
for (int i = 1; i <= 31; i++) p *= 2; // 連乘算 2 的次方(9.8:別用 pow)
cout << p << '\n';
return 0;
}
執行結果:
2147483648
int 上限 2147483647,正是它減 1。順帶一提,9.6 那個「double 存整數的門檻」2^{53},現在你也能自己估了:(2^{10})^5 \times 2^3 \approx 8 \times 10^{15}。
動手試試看:先用近似法估 2^{24} 的量級(拆成 (2^{10})^2 \times 2^4),再改連乘程式印出實際值對答案(16777216——約 1.6 \times 10^7,估對了嗎?)。