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

C語言 Divide Error 除零錯誤完整解析與修正

     編輯:C 語言問答

錯誤代碼分析

#include        // 缺少標頭檔名稱
int main() {
    int i, w = 1;
    float e = 1.0, s;
    for (i = 1; i <= 20; i++) {
        w = w * i;      // w 為 int,13! = 6227020800 超過 32 位有號整數範圍 → 溢位
        s = 1 / w;      // 整數除法:1 / w (w>1 時結果為 0),非浮點除法
        e += s;
    }
    printf("\ne=%f", e);
    return 0;
}

三大核心錯誤

錯誤說明後果
標頭檔缺失#include 後無檔案名編譯錯誤
整數溢位w 為 int,13! 超過 INT_MAX (2,147,483,647)未定義行為,數值環繞變負或零
整數除法1 / w 兩邊皆整數,C 語言執行整數除法,結果截斷為整數w>1 時 s=0,w=0 時觸發 Divide Error (除零中斷)

為何會出現 Divide Error?

當 i=13 時,w = 13! 溢位導致 w = 0(或負數後續乘法變 0)。接著 s = 1 / 0 觸發硬體除零例外,程式被作業系統終止,顯示 Divide Error 或 Floating point exception。

正確修正版本

#include <stdio.h>

int main() {
    int i;
    double e = 1.0;   // 用 double 提高精度,e = 1 + 1/1! + 1/2! + ... + 1/20!
    double term = 1.0; // 當前項 1/i!

    for (i = 1; i <= 20; ++i) {
        term /= i;     // term = 1/i!  避免大數階乘溢位,累除更穩定
        e += term;
    }

    printf("e = %.15f\n", e);  // e ≈ 2.718281828459045
    return 0;
}

關鍵修正點解析

  1. 使用 double 而非 float:雙精度 15-16 位有效數字,單精度僅 6-7 位,計算 e 需高精度。
  2. 避免計算大階乘:改用遞推 term /= i 計算 1/i!,完全避開整數溢位與大數除法。
  3. 浮點除法:term 為 double,term / i 自動提升為浮點除法。
  4. 標準主函數:int main() 返回 0。

數學背景:自然對數底 e 的級數展開

e = Σ (1/k!) from k=0 to ∞ = 1 + 1/1! + 1/2! + 1/3! + ...

本題計算前 21 項 (k=0..20),雙精度下已達機器精度極限。

常見誤區對照表

錯誤寫法問題正確寫法
int w; w=w*i; s=1/w;整數溢位 + 整數除法double term=1; term/=i; e+=term;
float w; s=1/w;1 為整數,仍是整數除法後轉浮點s=1.0/w; 或 s=1.0f/w;
s=1/w; 後 w=0除零硬體異常演算法避免分母為零
void main()非標準int main()

除錯技巧:如何定位 Divide Error

  1. 編譯器警告:-Wall -Wextra 會提示「integer division in floating point context」或「division by zero」。
  2. GDB 除錯:run 崩潰後 bt 查看堆疊,print w 觀察變數值。
  3. 列印中間值:迴圈內 printf("i=%d, w=%d, s=%f\n", i, w, s); 即可看到 w 變 0 的瞬間。
  4. AddressSanitizer:-fsanitize=undefined 可捕捉除零、溢位等 UB。

總結

Divide Error 本質是 整數除以零觸發硬體異常。本題根因在於 整數階乘溢位導致分母變零,配合 整數除法語意誤解。修正核心:用浮點遞推避開大數運算,這是數值計算的基本功。

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