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

為什麼計算自然常數 e 的兩段程式碼結果誤差巨大?

     編輯:程式設計綜合問答

問題背景

在學習 Java 時,許多初學者會嘗試用程式計算自然常數 e(約 2.71828)。公式為:

e = 1 + 1/1! + 1/2! + 1/3! + ...

但兩段看似相似的程式碼,輸出結果卻相差甚遠:第一段輸出 2.71828182845,第二段卻只有 2.5868345。這究竟是為什麼?

程式碼對比

正確版本(for 迴圈)

double e = 1.0;
double a = 1.0;
for (int i = 1; i < 30; i++) {
    a = a / i;      // 遞推計算 1/i!
    e = e + a;      // 累加
}
System.out.println("e=" + e); // 輸出 2.71828182845

錯誤版本(while 迴圈)

double e = 1.0, a = 1.0;
double s = 1.0, n = 1.0, b = 0.0;
while (a >= 1e-6) {
    b = n;
    while (n > 0) {   // 這裡重複計算階乘,且修改了 n
        s = s * n;
        n = n - 1;
    }
    a = 1.0 / s;
    e = e + a;
    n++;
    n = ++b;          // 邏輯混亂,導致階乘計算錯誤
}
System.out.println(e); // 輸出 2.5868345

核心問題分析

第二段程式碼的主要缺陷在於:

  • 變數重複使用導致邏輯錯亂:n 既用作階乘計算的計數器,又用作外層迴圈的項數控制,內層 while(n>0) 會將 n 歸零,後續 n++ 和 n=++b 試圖恢復卻無法正確對應階乘項數。
  • 階乘計算方式錯誤:每次外層迴圈都從頭累乘 s = s * n,但 s 未重置,導致分母急劇增大,項值過快衰減,提前終止迴圈。
  • 冗餘變數干擾:b、s 等變數增加理解難度,實際上只需一個遞推變數即可。

正確寫法示範(C 語言)

double e = 1.0, a = 1.0;
double s = 1.0, n = 1.0;
while (a >= 1e-6) {
    a = 1.0 / s;   // 當前項值
    e = e + a;     // 累加
    n++;           // 下一項分母因子
    s = s * n;     // 遞推更新階乘
}
printf("e = %f\n", e); // 輸出 2.718282

關鍵點總結

  1. 計算級數求和時,遞推關係(如 term[i] = term[i-1] / i)比重複計算階乘更高效、更不易出錯。
  2. 避免在迴圈中對同一變數進行多重用途的修改,保持變數職責單一。
  3. 終止條件應根據項值大小(如 1e-6)而非固定次數,但必須確保項值計算正確。

掌握遞推思維,能讓你在處理泰勒展開、數值積分等問題時事半功倍。

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