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

PHP 浮點數精度陷阱:比較失效與取整偏差的解決方案

     編輯:PHP 相關知識

PHP 浮點數精度陷阱:比較失效與取整偏差的解決方案

浮點數精度問題是所有基於 IEEE 754 標準的語言通病,PHP 也不例外。本文剖析兩大典型場景並給出最佳實踐。

場景一:浮點數比較失效

<?php
$a = 0.2 + 0.7; // 0.8999999999999999
$b = 0.9;       // 0.9000000000000000
var_dump($a == $b); // bool(false)
?>

直接比較不可靠。解決方案:

  • BCMath 高精度比較:var_dump(bcadd(0.2, 0.7, 1) == '0.9'); // true。指定小數位數,返回字符串比較。
  • 容差比較:abs($a - $b) < 0.00001。適用於科學計算場景。
  • 整數化比較:金額轉分存儲(如 0.9 元 → 90 分),徹底規避浮點數。

場景二:取整函數異常

<?php
echo ceil(2.1 / 0.7); // 輸出 4,預期 3
printf("%.20f", 2.1 / 0.7); // 3.00000000000000044409
?>

因除法結果略大於 3,ceil 進位成 4。修正方法:

<?php
// 先四捨五入到足夠精度,再取整
echo ceil(round(2.1 / 0.7, 1)); // 3
?>

round($val, 1) 將誤差截斷,保證後續 ceil/floor/intval 正確。

最佳實踐總結

  1. **金融/金額計算**:全程使用整數(分/厘)或 BCMath/GMP 擴展。
  2. **一般科學計算**:使用 round() 控制精度後再比較或取整。
  3. **永遠不信任** == **比較浮點數**,改用 bccomp() 或容差判斷。
  4. **輸出顯示** 使用 number_format() 或 printf() 格式化,避免科學記數法。

擴展閱讀

PHP 官方文檔 浮點數 章節詳細說明了二進制表示限制。理解底層原理有助於在架構層面規避風險。

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