語法書 / AA 競程語法書 下冊 / 第十六單元 / 估計 2 的次方有多大

16.6 估計 2 的次方有多大

二進制不只藏在進制轉換題裡——整數型態的範圍全是 2 的次方。這一節教你一套「秒估 2^n 量級」的功夫,之後判斷「這個數塞不塞得下 int」「陣列開這麼大會不會 MLE」全靠它。

先把小的背熟(2^0 \sim 2^{10},唸幾遍就記得):

1,\ 2,\ 4,\ 8,\ 16,\ 32,\ 64,\ 128,\ 256,\ 512,\ 1024

核心近似只有一條:

2^{10} = 1024 \approx 1000 = 10^3

要估 2 的大次方,把指數拆成「10 的倍數+零頭」,套國二的指數律(同底數相乘、指數相加):

2^{31} = 2^{30} \times 2 = (2^{10})^3 \times 2 \approx (10^3)^3 \times 2 = 2 \times 10^9

實際的 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 上限

(估出來會略偏小:每次把 10241000 少算了 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。所以:

\text{int 上限} = 2^{31} - 1 = 2147483647 \approx 2.1 \times 10^9

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,估對了嗎?)。