首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 浮點數精度問題完全指南:成因、案例與解決方案

     編輯:PHP 綜合知識

PHP 遵循 IEEE 754 雙精度標準,浮點數以 64 位元儲存(1 位號、11 位指數、52 位尾數)。這導致許多十進位小數在二進位下無法精確表示,成為經典的「精度陷阱」。

經典案例重現

<?php
$f = 0.57;
echo intval($f * 100); // 輸出 56,而非預期的 57

$f = 0.58;
var_dump(intval($f * 100)); // 輸出 57

根本成因:二進位無限循環

以 0.57 為例,採「乘 2 取整」法轉二進位:

0.57 × 2 = 1.14 → 1
0.14 × 2 = 0.28 → 0
0.28 × 2 = 0.56 → 0
0.56 × 2 = 1.12 → 1
... 無限循環,無法終止

52 位尾數只能截斷近似值:

  • 0.57 實際儲存約為 0.56999999999999995
  • 0.58 實際儲存約為 0.57999999999999996

乘 100 後再 intval 截斷,自然得到 56 與 57。這不是 PHP Bug,而是 IEEE 754 固有特性。

解決方案對比

方法適用場景注意事項
round($val, $precision)一般四捨五入需求會四捨五入,非單純截斷
sprintf("%.Nf", $val)需固定小數位輸出回傳字串,需再轉型
bcmath / gmp金融、科學計算等高精度場景需安裝擴展,效能較低
整數運算(如以「分」為單位)貨幣計算避開浮點數,最推薦

最佳實踐建議

  1. 貨幣/金額務必用整數(分)或 bcmath,杜絕浮點數直接運算。
  2. 顯示層使用 number_format() 或 sprintf() 格式化。
  3. 比較浮點數時,設定容差值:abs($a - $b) < 1e-9。
  4. 理解 php.precision 僅影響輸出,不改變內部儲存值。

掌握這些原理與技巧,即可從容應對 PHP 浮點數精度問題,避免踩坑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved