2.10 整數溢位

圖 2-3:整數型態的範圍與溢位

什麼是溢位?

當一個變數存的值超過了它的型態能表示的範圍,就發生了溢位

正向溢位

#include <iostream>
#include <climits>
using namespace std;

int main() {
    int x = INT_MAX;    // INT_MAX = 2,147,483,647
    cout << "INT_MAX = " << INT_MAX << endl;

    x = x + 1;          // 溢位
    cout << "INT_MAX + 1 = " << x << endl;  // 通常輸出負數
    return 0;
}

執行結果(典型):

INT_MAX = 2147483647
INT_MAX + 1 = -2147483648

負向溢位

#include <iostream>
#include <climits>
using namespace std;

int main() {
    int x = INT_MIN;    // INT_MIN = -2,147,483,648
    cout << "INT_MIN = " << INT_MIN << endl;

    x = x - 1;          // 溢位
    cout << "INT_MIN - 1 = " << x << endl;  // 通常輸出正數
    return 0;
}

溢位的真實案例:計算乘積

避免溢位的方法

方法 1:使用 long long

#include <iostream>
using namespace std;

int main() {
    long long a = 100000, b = 100000;
    long long result = a * b;  // ✓ 不溢位
    cout << "Result: " << result << endl;
    return 0;
}

執行結果:

Result: 10000000000

方法 2:在乘法前轉型

#include <iostream>
using namespace std;

int main() {
    int a = 100000, b = 100000;
    long long result = (long long)a * b;  // ✓ 先轉成 long long,再相乘
    cout << "Result: " << result << endl;
    return 0;
}

(long long)a 這種寫法叫轉型——把 a 先「暫時當成 long long」看待,於是整個乘法就用 long long 來算。「轉型(型別轉換)」的概念下一單元 3.7 會再仔細解釋,這裡先照著用即可。)

方法 3:使用字面常數後綴

#include <iostream>
using namespace std;

int main() {
    long long result = 100000LL * 100000LL;  // ✓ 直接用 LL 後綴
    cout << "Result: " << result << endl;
    return 0;
}

動手試試看

試著執行以下程式,對比兩個結果:

#include <iostream>
using namespace std;

int main() {
    // 錯誤做法
    int bad = 50000 * 50000;
    cout << "int result: " << bad << endl;

    // 正確做法
    long long good = 50000LL * 50000LL;
    cout << "long long result: " << good << endl;

    return 0;
}