這是萊布尼茲級數的部分和,收斂於 ln(2) ≈ 0.693147。本文展示兩種實作方式並分析精度差異。
#include <stdio.h>
#include <math.h>
int main() {
double sum = 0.0;
for (int n = 1; n <= 100; n++) {
// (-1)^(n+1) 產生交替正負號:n=1 時為 +1, n=2 時為 -1
double sign = pow(-1, n + 1);
sum += sign / n;
}
printf("方法一結果:%.10f\n", sum);
printf("ln(2) 真值:%.10f\n", log(2.0));
printf("誤差:%.10f\n", fabs(sum - log(2.0)));
return 0;
}
#include <stdio.h>
int main() {
double sum = 0.0;
int sign = 1; // 正負號旗標
for (int n = 1; n <= 100; n++) {
sum += sign * (1.0 / n);
sign = -sign; // 翻轉正負號
}
printf("方法二結果:%.10f\n", sum);
printf("ln(2) 真值:%.10f\n", 0.6931471805599453);
return 0;
}
| 指標 | pow() 法 | 旗標法 |
|---|---|---|
| 執行速度 | 較慢(函數呼叫開銷) | 極快(簡單乘法) |
| 數值精度 | 良好 | 良好 |
| 程式碼清晰度 | 數學意圖明確 | 演算法意圖明確 |
1/n 整數除法會截斷為 0(n>1 時)。必須寫成 1.0/n 或 (double)1/n 強制浮點數除法。
// 兩兩分組版:收斂快一倍
double sum = 0.0;
for (int n = 1; n <= 50; n++) {
sum += 1.0 / (2 * n * (2 * n - 1));
}
printf("加速版結果:%.10f\n", sum);