在學習 Java 時,許多初學者會嘗試用程式計算自然常數 e(約 2.71828)。公式為:
e = 1 + 1/1! + 1/2! + 1/3! + ...
但兩段看似相似的程式碼,輸出結果卻相差甚遠:第一段輸出 2.71828182845,第二段卻只有 2.5868345。這究竟是為什麼?
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
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 等變數增加理解難度,實際上只需一個遞推變數即可。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
term[i] = term[i-1] / i)比重複計算階乘更高效、更不易出錯。1e-6)而非固定次數,但必須確保項值計算正確。掌握遞推思維,能讓你在處理泰勒展開、數值積分等問題時事半功倍。