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

浮點數比較陷阱:為什麼不能用 == 判斷零值?

     編輯:關於C語言

浮點數比較問題:正確判斷 float 是否為零

在 C/C++ 開發中,直接使用 x == 0 判斷浮點數是否為零是極其危險的常見錯誤。這篇文章深入解析浮點數表示原理,說明為什麼必須採用「絕對值小於極小值」的比較策略,並介紹標準庫提供的精度常數。

經典面試題

某大廠面試題:float x 與「零值」比較的正確 if 語句是?

  • A. if (x == 0)
  • B. if (x < 0.00001f)
  • C. if (fabs(x) < 0.00001f)
  • D. if (x > -0.00001f)

正解:C。fabs() 取絕對值,確保同時覆蓋正負誤差範圍。

根本原因:二進制表示誤差

浮點數(float/double)依照 IEEE 754 標準以二進制科學記號儲存。許多十進制小數(如 0.1、0.01)在二進制中是無限循環小數,無法精確表示,只能存儲近似值。因此,看似簡單的運算結果往往帶有微小誤差:

float x = 0.1f + 0.2f; // x 可能等於 0.30000001
if (x == 0.3f) // 判斷失敗!

正確比較模式

判斷兩浮點數 a、b 是否「相等」:

#define EPSILON 1e-6f // 或根據精度需求調整
if (fabs(a - b) < EPSILON) { /* 視為相等 */ }

判斷 x 是否為零:

if (fabs(x) < EPSILON) { /* x 視為零 */ }

標準庫精度常數

C 標準庫 <float.h> 定義了機器相關的極小值:

  • FLT_EPSILON:float 能表示的最小正數,使得 1.0 + EPSILON != 1.0(約 1.19e-7)。
  • DBL_EPSILON:double 對應值(約 2.22e-16)。
  • LDBL_EPSILON:long double 對應值。

使用方式:

#include <float.h>
#include <math.h>

if (fabs(x) < FLT_EPSILON) { /* float 零值判斷 */ }
if (fabs(x) < DBL_EPSILON) { /* double 零值判斷 */ }

延伸影響:switch 不能用浮點數

因為浮點數無法精確比較,C 標準禁止在 switch 條件中使用 float/double,也不能作為 case 標籤。若需分支判斷,請改用整數枚舉或字串比對。

最佳實踐總結

  1. 永不使用 == 或 != 直接比較浮點數。
  2. 採用 fabs(a - b) < EPS 模式,EPS 根據業務精度選擇(如金融用 1e-4,科學計算用 1e-9)。
  3. 優先使用 FLT_EPSILON/DBL_EPSILON 等標準常數,提高程式碼可移植性。
  4. 輸出除錯時,用 printf("%.17g", x) 觀察完整精度,而非預設的 %f(僅 6 位小數)。

記住:浮點數比較的核心不是「相等」,而是「足夠接近」。

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