在 C/C++ 開發中,直接使用 x == 0 判斷浮點數是否為零是極其危險的常見錯誤。這篇文章深入解析浮點數表示原理,說明為什麼必須採用「絕對值小於極小值」的比較策略,並介紹標準庫提供的精度常數。
某大廠面試題:float x 與「零值」比較的正確 if 語句是?
if (x == 0)if (x < 0.00001f)if (fabs(x) < 0.00001f)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 標籤。若需分支判斷,請改用整數枚舉或字串比對。
== 或 != 直接比較浮點數。fabs(a - b) < EPS 模式,EPS 根據業務精度選擇(如金融用 1e-4,科學計算用 1e-9)。FLT_EPSILON/DBL_EPSILON 等標準常數,提高程式碼可移植性。printf("%.17g", x) 觀察完整精度,而非預設的 %f(僅 6 位小數)。記住:浮點數比較的核心不是「相等」,而是「足夠接近」。