PHP 浮點型與整型比較的小坑

今天我們來看一個在 PHP 中比較有意思的事:浮點數(floats)

<?phpdie(var_dump(1200.85 * 100 === 120085));

你認為上面的代碼會出現什麼結果呢?1. true 2. false 3. 這種比較視情況而定

其實很簡單,因為在這裡,我們使用了 === 來做比較,所以這個結果很清晰的就是 false,

因為我們左邊是一個 floats 類似的數,右邊是一個 int 類型的數。

這是沒什麼可以特別討論的。

那如果是這樣呢?

<?phpdie(var_dump(1200.85 * 100 == 120085));

就是我們使用 == 來比較的時候呢?

你可能會這樣想:左邊 120085,右邊 120085,所以結果是 true。

如果你這樣想的話,那你就錯了。其實你運行上面的代碼,結果回是 false。

然而,我是說然而!你再嘗試修改一下數字,在運行一次代碼,比如這樣:

<?phpdie(var_dump(1200.81 * 100 == 120081));

你會發現結果非常神奇,這個時候結果是 true,所以說,這種比較其實還真是視情況而定

那麼問題出現在哪裡呢?我們試著運行下面的代碼:

<?php var_dump(1200.85 * 100);die(var_dump(120085));

結果會類似這樣:

float(120085) int(120085)

好像沒看出什麼核心區別,我們這樣再試試:

die(var_dump(120085 - 1200.85 * 100));

這個時候的結果應該是這樣:

float(1.4551915228367E-11)

這就說明問題了,其實這個結果並不是 0 ,而是一個很小的 floats 類似的數。

如果你看 PHP 文檔的時候:http://php.net/manual/zh/lang...

有注意那個很大的 Warning 的話,你應該就會明白:這裡的核心問題其實就是浮點數的精度!

那這樣的話,我們如何比較才是我們期望的值呢?

答案就是使用 round() 函數,像是這樣:

die(var_dump(round(1200.85 * 100) == 120085));

所以吧,在使用 PHP 做這些精度計算比較的時候,一定要實測它的比較結果,或者是使用一些保險的手段進行比較,不然就會吃大虧!

關注公眾號 codecasts ,每天更新 PHP Laravel 技能

推薦閱讀:

檢測 PHP 應用的代碼複雜度
手把手編寫自己的 PHP MVC 框架實例教程
如何在Mac上優雅的開發PHP項目?
如何看待Facebook 的 HHVM 引擎將轉用 Hack 語言?

TAG:互联网 | 编程 | PHP |