首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 整型字面值溢出陷阱:3751³ 為什麼算錯?long long 與 pow() 的本質區別

     編輯:程式設計疑難解答

現象複現


cout << 3751 * 3751 * 3751 << endl; // 輸出錯誤值(如 -130...)
cout << pow(3751, 3) << endl;       // 輸出正確值
long long a = 3751;
cout << a * a * a << endl;          // 輸出正確值

根本原因:整型字面值默認類型是 `int`

表達式類型推導過程結果
3751 * 3751 * 3751字面值 `3751` 是 `int` (32位) → 相乘過程全程 `int` 運算 → 溢出 (超過 2^31-1) → 未定義行為/環繞錯誤
pow(3751, 3)`pow(double, double)` → 參數隱式轉 `double` (64位浮點) → 浮點運算無溢出 → 返回 `double`正確 (近似值)
long long a=3751; a*a*a變量 `a` 是 `long long` (64位) → 運算提升為 `long long` → 64位整數運算無溢出正確 (精確值)

關鍵知識點

  1. 字面值類型規則:無後綴整數字面值優先匹配 `int` → `long` → `long long`(C++11)。3751 落在 `int` 範圍內,故為 `int`。
  2. 整數提升與常規算術轉換:運算符兩側操作數類型不同則向高精度提升。`int * int` 仍為 `int`;`long long * int` 提升為 `long long`。
  3. 溢出後果:有符號整數溢出是**未定義行為 (UB)**,編譯器可任意優化導致不可預期結果。

避坑指南


// 1. 字面值加後綴強制類型
cout << 3751LL * 3751 * 3751 << endl; // 首個 LL 提升全表達式

// 2. 使用變量承接(推薦,語義清晰)
long long base = 3751;
cout << base * base * base << endl;

// 3. 大數精確運算用專用庫
// boost::multiprecision::cpp_int big = 3751;
# big = big * big * big; // 任意精度

總結

字面值不帶後綴就是 `int`,`int` 運算溢出不可靠。 只要涉及可能超出 21 億的整數計算,聲明 `long long` 變量或加 `LL` 後綴,將類型鎖定在 64 位,從源頭杜絕溢出 Bug。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved