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

C 語言浮點數比較陷阱:為什麼不能直接用 == 判斷相等?

     編輯:C 語言問答

C 語言浮點數比較陷阱:為什麼不能直接用 == 判斷相等?

浮點數在計算機中以二進制科學計數法存儲(IEEE 754),許多十進制小數無法精確表示,導致直接用 == 比較極不可靠。

問題代碼分析

#include "stdio.h"
main() {
    float c, a=0.0039, d=-0.9347, b, f1, f2;
    double la, lo;
    scanf("%lf", &la);
    scanf("%lf", &lo);
    if ((fabs(la-65.079) < 0.001) && (fabs(lo-63.9775) < 0.0001)) {
        b=28.4; f1=8.7; f2=25.9;
    }
    c = b + a*f1 + d*f2;
    printf("%f", c);
}

存在的問題

  1. 缺少頭文件:fabs 需 <math.h>
  2. 浮點數精度不足:float 僅 6-7 位有效數字,計算累積誤差大
  3. 直接比較風險:雖代碼用 fabs() < epsilon,但變量類型應升級
  4. main 返回類型:應為 int 並 return 0

修正版代碼

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

int main() {
    double c, a=0.0039, d=-0.9347, b, f1, f2;
    double la, lo;

    scanf("%lf", &la);
    scanf("%lf", &lo);

    // 使用 epsilon 比較,雙精度更安全
    const double EPS1 = 0.001;
    const double EPS2 = 0.0001;
    if (fabs(la - 65.079) < EPS1 && fabs(lo - 63.9775) < EPS2) {
        b = 28.4; f1 = 8.7; f2 = 25.9;
    } else {
        // 明確初始化,避免未定義行為
        b = f1 = f2 = 0;
    }

    c = b + a*f1 + d*f2;
    printf("%f\n", c);
    return 0;
}

浮點數比較最佳實踐

// 通用相等判斷函數
bool float_equal(double a, double b, double epsilon) {
    return fabs(a - b) < epsilon;
}

// 相對誤差版本(適合大數值)
bool float_equal_rel(double a, double b, double rel_eps) {
    double diff = fabs(a - b);
    double max_abs = fmax(fabs(a), fabs(b));
    return diff <= rel_eps * max_abs;
}

關鍵建議

  • 默認使用 double,除非記憶體/帶寬極度受限
  • 比較時永遠使用 epsilon 範圍,不可用 ==
  • 財務/金融計算禁用浮點數,改用定點數或整數分單位
  • 包含 <math.h> 並鏈接數學庫(-lm)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved