浮點數(實型)是 C 語言處理小數、科學計數值的核心類型。本文系統講解十進制小數與指數形式、IEEE 754 存儲佈局、float/double/long double 三種類型差異、捨入誤差成因與規避策略,助你在數值計算中避開精度陷阱。
| 形式 | 示例 | 說明 |
|---|---|---|
| 十進制小數 | 0.0 25.0 5.789 .13 300. -267.8230 | **必須包含小數點**,否則視為整數 |
| 指數形式 | 2.1E5 3.7E-2 -2.8E-2 .5E7 | a E n 表示 a × 10ⁿ;E 可大小寫,階碼必須為整數 |
非法示例:345(無小數點)、E7(缺尾數)、53.-E3(符號位置錯)、2.7E(缺階碼)。
浮點數按「科學計數法」二進制存儲:(-1)^S × 1.M × 2^(E - bias)。
| 類型 | 佔用位數 | 符號位 | 指數位 | 尾數位 | 偏移量 | 十進制有效位數 | 數值範圍約略 |
|---|---|---|---|---|---|---|---|
float (單精度) | 32 | 1 | 8 | 23 | 127 | ~7 位 | ±3.4E-38 ~ ±3.4E+38 |
double (雙精度) | 64 | 1 | 11 | 52 | 1023 | ~15-16 位 | ±1.7E-308 ~ ±1.7E+308 |
long double | 80/128 | 1 | 15/112 | 64/112 | 16383/16383 | ~19/34 位 | 視實現而定 |
尾數隱含最高位 1(規格化數),實際精度比顯式位數多 1 位。
float x, y; // 單精度,4 字節
double a, b, c; // 雙精度,8 字節,**默認推薦類型**
long double d, e; // 擴展精度,視平台而定
關鍵規定:浮點常量(如 3.14)默認類型為 double;float 常量需後綴 f/F(3.14f)。
有限位數無法精確表示所有實數,導致:
0.1 二進制無限循環,float 存為 0.10000000149…1.0/3.0*3.0 != 1.0。1e8 + 1 == 1e8(float 7 位有效數字不足以區分)。#include <stdio.h>
int main(void) {
float a = 123456.789e5f; // 大數
float b = a + 20.0f; // +20 可能完全丟失
printf("a=%f\nb=%f\n", a, b); // 輸出可能相同
float f = 33333.33333f;
double d = 33333.333333333333;
printf("float: %.10f\n", f); // 33333.332031... (僅 7 位可信)
printf("double: %.10f\n", d); // 33333.333333... (15 位可信)
return 0;
}
| 場景 | 建議 |
|---|---|
| 金融/貨幣計算 | **禁用浮點**;用整數存「分」或定點數庫 |
| 一般科學計算 | 優先 double;僅記憶體/帶寬極敏感時用 float |
| 比較浮點數相等 | 用絕對/相對誤差:fabs(a-b) <= eps * fmax(fabs(a), fabs(b)) |
| 輸出格式控制 | printf("%.6f", x) 指定小數位;%e 科學計數法 |
| 常量後綴 | 3.14f (float)、3.14 (double)、3.14L (long double) |
double 為默認最佳選擇,精度與範圍均大幅優於 float。