金額計算、比例顯示、統計報表中頻繁需要「保留兩位小數」。PHP 提供多種方式,行為卻有細微差異:四捨五入、直接截斷、向上/向下取整。本文整理最常用模式並標註適用場景。
sprintf / number_format$num = 123213.666666;
// 方式一:sprintf 格式化字串(推薦,返回字串)
echo sprintf("%.2f", $num); // 123213.67
// 方式二:number_format(可指定千分位分隔符)
echo number_format($num, 2, '.', ','); // 123,213.67
// 方式三:round 函數(返回浮點數,後續計算友好)
echo round($num, 2); // 123213.67
$num = 123213.666666;
// 技巧:先取三位四捨五入,再截去最後一位
echo sprintf("%.2f", substr(sprintf("%.3f", $num), 0, -1)); // 123213.66
// 更直觀:bcmath 高精度截斷(需擴展)
echo bcdiv($num, 1, 2); // 123213.66
// 或數學運算:floor($num * 100) / 100
echo floor($num * 100) / 100; // 123213.66
// 向上取整:>= 該數的最小整數
echo ceil(4.3); // 5
echo ceil(9.999); // 10
echo ceil(-4.3); // -4 (負數向零方向)
// 向下取整:<= 該數的最大整數
echo floor(4.3); // 4
echo floor(9.999); // 9
echo floor(-4.3); // -5 (負數遠離零方向)
// 整數部分提取(向零截斷)
echo intval(4.9); // 4
echo intval(-4.9); // -4
// PHP round() 預設使用「銀行家捨入」:.5 向最近偶數靠攏
echo round(1.5); // 2
echo round(2.5); // 2 ← 注意!不是 3
echo round(3.5); // 4
// 強制傳統四捨五入 (PHP_ROUND_HALF_UP)
echo round(2.5, 0, PHP_ROUND_HALF_UP); // 3
// 浮點數精度陷阱
echo sprintf("%.2f", 0.58 * 100); // 57.99 ≠ 58.00
// 解決:bcmath 或 先轉整數運算
echo (int)(0.58 * 100 + 0.5); // 58
echo bcmul('0.58', '100', 0); // 58
| 需求 | 推薦函數 | 返回類型 | 備註 |
|---|---|---|---|
| 顯示金額、比例(四捨五入) | sprintf("%.2f", $n) | string | 直接輸出模板,千分位用 number_format |
| 後續仍需參與計算 | round($n, 2) | float | 注意銀行家捨入,金融建議 PHP_ROUND_HALF_UP |
| 截斷不進位(如利率截斷) | floor($n*100)/100 或 bcdiv | float/string | bcmath 無精度損失,推薦金融系統 |
| 最小整數單位(如庫存箱數) | ceil($total/$perBox) | int | 向上取整確保足夠 |
| 最大整數單位(如分頁總頁數) | floor($total/$perPage) | int | 向下取整 |
int,僅輸出時除 100 格式化,徹底避開浮點誤差。bcmath / gmp:高精度數學擴展,金融、科研計算必備。declare(strict_types=1):強制類型檢查,避免隱式轉型導致精度竄改。選對工具、懂原理、設防線,才能在浮點數的世界裡游刃有餘。