float 輸出精度問題:為何 11111.11111 變 11111.111328?
float a = 11111.11111f;
double b = 11111.111111111111;
printf("%f\n%f\n", a, b);
// 輸出:
// 11111.111328
// 11111.111111
float (IEEE 754 binary32):**1 符號位 + 8 指數位 + 23 尾數位** ≈ **7-8 位十進制有效數字**。11111.11111 整數部份 5 位,僅剩 **2-3 位小數精度可靠**。0.11111 在二進制是**無限循環小數**,存入 float 時被捨入為最接近的二進制近似值。11111.111328(實際儲存值最近似的十進制表示)。這是**經驗法則**:float 約 7.22 位十進制有效數字 (log10(2^24))。整數部份佔 5 位 → 小數可靠約 2 位。**實際可靠位數取決於具體數值大小**,非固定截斷。
printf("%.2f\n", a); → 11111.11(四捨五入顯示)。long long,顯示時手動插入小數點。double:15-16 位有效數字,誤差極小。==:fabs(a-b) < 1e-6 (float) / 1e-12 (double)。
#include
#include
int main(void) {
float a = 11111.11111f;
double b = 11111.111111111111;
printf("預設 %%f (6位小數) : a=%f b=%f\n", a, b);
printf("指定 %.2f (2位小數) : a=%.2f b=%.2f\n", a, b);
printf("指定 %.4f (4位小數) : a=%.4f b=%.4f\n", a, b);
printf("科學記號 %%e : a=%e b=%e\n", a, b);
printf("十六進制浮點 %%a (精確位元) : a=%a b=%a\n", a, b); // C99
// 比較示範
float x = 0.1f + 0.2f;
float y = 0.3f;
printf("0.1+0.2 == 0.3 ? %s (差值 %.2e)\n",
fabsf(x - y) < 1e-6 ? "true" : "false", fabsf(x - y));
return 0;
}
float 約 7 位十進制有效數字,**非小數點後 7 位**。%.Nf),否則預設 6 位小數可能顯示雜訊。%f, %e, %a、%.Nf)。float**,用 double 或定點數/十進制庫。