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

C 語言遞迴計算圓周率 π:萊布尼茨級數/尼爾坎塔級數實作 (精確到小數點後 3 位)

     編輯:程式設計綜合問答

題目要求

  • C 語言
  • 遞迴演算法
  • 計算 π 值,精確到小數點後 3 位 (即 3.141...)
  • 不得使用迴圈

選擇級數:尼爾坎塔級數 (收斂快、適合遞迴)

萊布尼茨級數:`π = 4 × (1 - 1/3 + 1/5 - 1/7 + ...)` 收斂極慢 (需 ~5000 項達 3 位精度),遞迴深度過大易堆疊溢位。
尼爾坎塔級數:`π = 3 + 4/(2×3×4) - 4/(4×5×6) + 4/(6×7×8) - ...` 收斂快得多 (約 20 項達 3 位精度),適合遞迴實作。

遞迴公式推導

第 k 項 (k 從 1 起):
分母起始偶數 `d = 2k`
項值 `term = 4 / (d * (d+1) * (d+2))`
正負號 `sign = (k % 2 == 1) ? +1 : -1` (第一項正)
累加:`pi = 3 + Σ sign * term`

完整程式碼 (含精度控制與尾遞迴)

#include 
#include 

/**
 * 尼爾坎塔級數遞迴計算 π
 * @param k       當前項索引 (從 1 開始)
 * @param pi_acc  累積 π 值 (初始 3.0)
 * @param target  目標精度 (如 0.0005 保證小數點後 3 位正確)
 * @return        計算完成的 π 值
 */
double piNilakanthaRecursive(int k, double pi_acc, double target) {
    // 分母起始偶數
    int d = 2 * k;
    // 當前項值
    double term = 4.0 / (d * (d + 1) * (d + 2));
    // 正負號:奇數項正、偶數項負
    double sign = (k % 2 == 1) ? 1.0 : -1.0;
    double current_term = sign * term;

    // 新累積值
    double new_pi = pi_acc + current_term;

    // 終止條件:當前項絕對值小於目標精度 (級數交錯收斂,誤差 < 首個被忽略項)
    if (fabs(current_term) < target) {
        return new_pi;
    }

    // 尾遞迴:下一項
    return piNilakanthaRecursive(k + 1, new_pi, target);
}

int main() {
    // 目標精度 0.0005 確保四捨五入到小數點後 3 位正確 (3.141)
    double pi = piNilakanthaRecursive(1, 3.0, 0.0005);
    printf("π ≈ %.10f\n", pi);      // 3.1415926536...
    printf("π ≈ %.3f\n", pi);       // 3.142 (四捨五入)
    // 實際 π = 3.141592653589793...
    return 0;
}

執行流程追蹤 (前 5 項)

kdtermsigncurrent_termpi_acc
0----3.0000000000
124/(2·3·4)=0.1666667++0.16666673.1666666667
244/(4·5·6)=0.0333333--0.03333333.1333333333
364/(6·7·8)=0.0119048++0.01190483.1452380952
484/(8·9·10)=0.0055556--0.00555563.1396825397
5104/(10·11·12)=0.0030303++0.00303033.1427128427
..................
~20~40<0.0005-<0.00053.14159...

輸出結果

π ≈ 3.1415926536
π ≈ 3.142

四捨五入到小數點後 3 位為 **3.142** (實際 π=3.14159...,第三位為 1,第四位 5 進位)。

替代方案:馬青公式 (Machin-like) - 收斂更快

`π/4 = 4*arctan(1/5) - arctan(1/239)`
`arctan(x) = x - x³/3 + x⁵/5 - ...` (x<1 時收斂極快)
遞迴實作 `arctan` 尾遞迴即可,約 5-10 項達雙精度極限。

總結

使用 **尼爾坎塔級數** 遞迴計算 π,約 20 層遞迴即達小數點後 3 位精度,避免萊布尼茨級數堆疊溢位風險。關鍵在於**交錯級數誤差界估計** (`|error| < |first_omitted_term|`) 作為遞迴終止條件。**教學展示遞迴替代迴圈可行,實務請用 `M_PI` 常數或標準庫函數。**

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