利用 截斷特性:(int)x 直接捨棄小數部分。若先加 0.5 再截斷,則:
x = 1.2 → 1.7 → 1(捨去)x = 1.6 → 2.1 → 2(進位)float f = 1.54536f;
f = (int)(f * 10 + 0.5f) / 10.0f;
// 步驟分解:
// 1. f*10 = 15.4536
// 2. +0.5 = 15.9536
// 3. (int) 截斷 = 15
// 4. /10.0 = 1.5
優先級由高到低:
1. () 括號
2. (int) 強制轉型
3. * / %
4. + -
// 因此 (int)(f*10+0.5) 先算括號內加法,再轉型,最後除法
= 0)
return floor(val * factor + 0.5) / factor;
else
return ceil(val * factor - 0.5) / factor; // 負數向遠離零方向
}
// C99 標準庫直接可用
// #include
// double round(double x); // 四捨五入到整數
// double roundf(float x);
// long lround(double x); // 回傳 long
// 保留 n 位:round(val * 1eN) / 1eN
| 需求 | 方法 | 說明 |
|---|---|---|
| 僅顯示保留 2 位 | printf("%.2f", val); | 不改變數值,僅輸出格式 |
| 後續計算需精確值 | val = round_n(val, 2); | 實際修改數值,避免誤差累積 |
| 金融/貨幣計算 | 整數分單位或 decimal 庫 | 避免二進位浮點誤差(如 0.1 無法精確表示) |
(int)(f + 0.5) 只能四捨五入到整數,非小數位。+0.5 會產生錯誤方向(如 -1.6 → -1 應為 -2),需分正負處理或用 round()。float 累加大量金額會產生精度漂移,關鍵計算請用 double 或整數分。