2010-11-08 58 views
6

可能重複:
PHP Math Precision((171.36/1.19)== 144)是否爲假?

這裏是PHP

一個示例代碼
echo (171.36/1.19) 
//[PHP] result: 144 
//[JavaScript] result: 144.00000000000003 
//[Manual] result : 144 

$var1 = 144; 
$converted = 171.36/1.19 


//Variable 1 is less than Converted? 
echo (($var1 < $converted)?"Yes":"No") 
//result: Yes 

//Variable 1 is equal to Converted? 
echo (($var1 == $converted)?"Yes":"No") 
//result: No 

echo (($converted == 144)?"Yes":"No") //--> NO 
echo (("144.00" == 144)?"Yes":"No") //--> YES 

你能不能給我一個簡單的解釋/回答,並告訴我說,PHP不越野車。

+25

電離輻射會導致CPU產生不正確的結果。我在我的辦公桌上放了一瓶碘酒,每次浮點平等測試都失敗了。 – mikerobi 2010-11-08 15:05:03

+2

我以爲你應該服用2.1粒?有什麼差距? – webbiedave 2010-11-08 16:36:43

回答

16

這是固有地涉及一定數量的錯誤的浮點計算的結果。任意實數不能精確地以大多數語言(包括PHP)使用的浮點格式存儲。您會在許多其他語言中看到類似的結果。

http://php.net/manual/en/language.types.float.php(閱讀粉紅大盒)

+1

+1可能是最好的答案,因爲它甚至涉及到PHP手冊。 – cgp 2010-11-08 15:09:05

+0

我同意; +1指向PHP手冊,這解釋了這個不幸的常見誤解。 – Randolpho 2010-11-08 15:10:54

19

你已經看到結果足夠接近144,這是將它轉換爲字符串時顯示的值 - 但它是而不是剛好是144,這就是爲什麼你在倒數第二行得到「否」 。

這與人們一次又一次碰到的浮點數相同。

171.36和1.19都不能在二進制浮點類型中精確表示。所以PHP對它們使用非常接近的近似值。當您執行算術運算時,考慮到涉及原始數據的數據類型的限制(即「不完全」您所期望的),結果將盡可能精確。

底線:除非是非常特殊的情況,否則不要直接比較浮點值是否相等。通常最好在一定的容差內測試它們(例如,在144-0.00001和144 + 0.00001之間的值)。

+0

[新聞快訊:浮點數不是無限精確的。詳細信息請參閱10:05000000004。](http://twitter.com/CrystalEmpGames/status/27160772411) – 2010-11-09 18:23:53

1

PHP不是越野車。它僅顯示144,因爲它在將浮點數轉換爲字符串以便打印時將其舍入爲12位有效數字。

如果將數字打印爲17位小數點,您將看到結果確實爲144.00000000000003,與Javascript的結果相同。

(其他的答案也解釋了爲什麼結果不完全是144不已,我不打算在此不再重複。)

示例代碼見http://www.ideone.com/u0yB8

5

The Floating-Point Guide

爲什麼我的數字,像0.1 + 0.2加起來一個漂亮的圓0.3,而是我得到一個奇怪>導致像0.30000000000000004?

因爲在內部,計算機使用的格式(二進制浮點)不能準確地表示 表示數字,如0.1,0.2或0.3。

當編譯或解釋代碼時,您的「0.1」已經以該格式四捨五入到最接近的數字,甚至在計算髮生之前會導致小的舍入誤差。

基本上,當你寫的文字171.36到您的代碼和代碼解釋,計算機將使用數量是不是,事實上,171.36 - 所以一點也不奇怪,它會產生不同的結果當用於計算時。