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

C語言浮點數比較錯誤:期中考試男女人數計算題修正

     編輯:程式設計綜合問答

經典數學題:參考人數380-450人,總平均76分,男生平均75分,女生平均80.1分,求男女人數。C語言雙循環暴力求解時,直接用==比較浮點數導致無輸出。本文解析錯誤原因並給出正確代碼。

問題代碼

if (75*a + 80.1*b == (a+b)*76)  // 錯誤:浮點數直接比較
    printf("男生:%d, 女生:%d\n", a, b);

錯誤原因

  • 80.1 在二進制浮點數中無法精確表示
  • 計算結果存在微小誤差(如 76.0000001 vs 76.0)
  • == 要求完全相等,條件永不成立

正確解法:引入容差 EPS

#include <stdio.h>
#include <math.h>

#define EPS 1e-3  // 0.001 足夠覆蓋誤差

int main() {
    int a, b;
    for (a = 0; a <= 450; a++)
        for (b = 0; b <= 450; b++)
            if ((380 <= a+b && a+b <= 450) &&
                fabs(75*a + 80.1*b - (a+b)*76) < EPS)
                printf("男生:%d, 女生:%d\n", a, b);
    return 0;
}

數學優化:化簡方程避免浮點數

原方程:75a + 80.1b = 76(a+b)
整理得:75a + 80.1b = 76a + 76b → 4.1b = a → 41b = 10a

即 a : b = 41 : 10,設 a = 41k, b = 10k,總人數 51k 在 380-450 之間。
k=8 時 51×8=408 符合,a=328, b=80。
純整數運算,零誤差,O(1) 秒解。

優化代碼

int main() {
    for (int k = 1; ; k++) {
        int total = 51 * k;
        if (total > 450) break;
        if (total >= 380) {
            printf("男生:%d, 女生:%d\n", 41*k, 10*k);
        }
    }
    return 0;
}

總結

  1. 浮點數絕不用 == 比較,必須用 fabs(x-y) < EPS
  2. 遇到小數係數方程,優先嘗試乘以10的冪次轉整數,消除誤差源頭
  3. 數學建模優於暴力枚舉,效率提升萬倍
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved