PHP 是弱型別語言,型別自動轉換雖方便,但強制轉型(casting)在處理浮點數時卻暗藏精度陷阱。稍有不慎,財務計算、比對邏輯即會產生難以察覺的偏差。
echo (int) 123.999999999999999; // 124 (非 123!)
echo (int) -1.999999999999999; // -1
echo (int) -1.9999999999999999; // -2 (多一個 9 就翻車)
echo (int) -0.99999999999999999; // -1
echo (int) -10.999999999999999; // -10
echo (int) -1000.9999999999999; // -1001
echo (int) -9999999999; // -1410065407 (溢位,結果未定義)
(int) 只是捨棄小數部份,不做四捨五入。0.1 + 0.7 實際儲存為 0.7999999999999999,乘 10 後為 7.999999999999999,轉整數得 7 而非預期 8。「當從浮點數轉換成整數時,將向零取整。如果浮點數超出了整數範圍,則結果不確定,因為沒有足夠的精度使浮點數給出一個確切的整數結果。在此情況下沒有警告,甚至沒有任何通知!」
bcmath 或 gmp 任意精度擴展,或以「分」為單位存儲整數運算。(int) round($float) 或 intval(round($float))。(int)(浮點運算式):先存入變數,再 round(),最後 intval()。abs($a - $b) < 1e-9 容差比較,切勿用 ==。記住:精度不夠,關我鳥事? 不,關系統穩定性大事。請謹慎對待每一次強制型別轉換。