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

C 語言習題解析:分數序列前 20 項求和

     編輯:程式設計綜合問答

題目背景

《C 程序設計(第四版)》習題 5-10 要求計算分數序列 2/1 + 3/2 + 5/3 + 8/5 + 13/8 + 21/13 ... 前 20 項的和。這是一個分子、分母皆為斐波那契數列變體的序列。

常見錯誤:整數除法導致精度丟失

許多初學者編寫如下代碼,但輸出結果為 21.000000,而標準答案約為 32.660261:

#include <stdio.h>

int fenzi(int n);
int fenmu(int m);

int main() {
    int i;
    float s = 0, tem;
    for (i = 1; i <= 20; i++) {
        tem = fenzi(i) / fenmu(i);  // 錯誤:整數除法
        s = s + tem;
    }
    printf("%f", s);
    return 0;
}

int fenzi(int n) {
    if (n == 1) return 2;
    else if (n == 2) return 3;
    else return (fenzi(n-2) + fenzi(n-1));
}

int fenmu(int m) {
    if (m == 1) return 1;
    else if (m == 2) return 2;
    else return (fenmu(m-2) + fenmu(m-1));
}

原因分析: fenzi(i) 與 fenmu(i) 均返回 int,C 語言中整數相除會截斷小數部分,導致每一項的值都變成 1,累加 20 次結果為 20(加上浮點數誤差顯示 21)。

正確做法:強制類型轉換為浮點數

在除法運算前將任一操作數轉為 double(或 float),即可得到精確的小數結果:

tem = (double)fenzi(i) / (double)fenmu(i);

完整修正版代碼:

#include <stdio.h>

int fenzi(int n);
int fenmu(int m);

int main() {
    int i;
    float s = 0, tem;
    for (i = 1; i <= 20; i++) {
        tem = (double)fenzi(i) / (double)fenmu(i);  // 關鍵修正
        s = s + tem;
    }
    printf("%f", s);  // 輸出 32.660261
    return 0;
}

int fenzi(int n) {
    if (n == 1) return 2;
    else if (n == 2) return 3;
    else return (fenzi(n-2) + fenzi(n-1));
}

int fenmu(int m) {
    if (m == 1) return 1;
    else if (m == 2) return 2;
    else return (fenmu(m-2) + fenmu(m-1));
}

進階優化建議

  • 遞歸計算斐波那契數列效率較低(重複計算),可改用迭代或動態規劃預先填充陣列。
  • 累加變數 s 建議使用 double 以提高精度。
  • 輸出格式可用 printf("%.10f", s) 控制小數位數。

總結

本題核心考點是 整數除法截斷 與 浮點數類型轉換。只要在除法前加上 (double) 強轉,即可獲得正確答案。同時也提醒初學者注意遞歸的性能問題,實際工程中優先選擇迭代實現。

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