2011-07-27 144 views
0

我期望所有下面的比較是bool(true),但它們不是。 任何人都可以解釋這一點嗎?PHP:浮點數學運算和比較

test.php的

<?php 

$f = 12; 
$f += 5.95; 
$f += 5.95; 
$f += 5.95; 

echo 'var_dump($f) = '; 
var_dump($f); 

echo 'var_dump($f == \'29.85\') = '; 
var_dump($f == '29.85'); 

echo 'var_dump($f == 29.85) = '; 
var_dump($f == 29.85); 

echo 'var_dump($f == (float)\'29.85\') = '; 
var_dump($f == (float)'29.85'); 

echo 'var_dump($f == \'29.85\') = '; 
var_dump((string)$f == '29.85'); 

echo 'var_dump(round($f, 2) == \'29.85\') = '; 
var_dump(round($f, 2) == '29.85'); 

$ PHP test.php的

var_dump($f) = float(29.85) 
var_dump($f == '29.85') = bool(false) 
var_dump($f == 29.85) = bool(false) 
var_dump($f == (float)'29.85') = bool(false) 
var_dump($f == '29.85') = bool(true) 
var_dump(round($f, 2) == '29.85') = bool(true) 

$ PHP -v

PHP 5.2.14 (cli) (built: Jul 23 2010 15:23:00) 
Copyright (c) 1997-2010 The PHP Group 
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies 
    with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans 
+2

的可能重複: http://stackoverflow.com/questions/3148937/compare-floats-in-php – DhruvPathak

回答

5

浮點數有精度的限制。雖然它取決於系統,但PHP通常使用IEEE 754雙精度格式,即 ,由於以1.11e-16的順序 進行四捨五入,因此它會給出最大相對誤差。非基本算術運算可能會給出更大的錯誤,當然,當多個操作複合時,必須考慮錯誤編程。

此外,有理數是在基座10,如0.1或0.7精確表示作爲 浮點數,沒有一個 精確表示作爲浮點數在基座2,其是 內部使用,不管尾數的大小。因此,他們 不能被轉換成其內部的二進制對應,沒有一個精度的小損失。這可能導致混亂的結果: 例如,地板((0.1 + 0.7)* 10)通常會返回7代替 預期8,由於內部表示將會像 7.9999999999999991118 ....

因此,不要將浮點數結果信任到最後一位,也不要將浮點數相等進行比較。

PHP documentation page

0

由於@Shakti辛格說,浮點數沒有精確存儲,所以我猜$ F實際存儲爲類似29.849999999999999 ......,所以不完全等於29.85 。

此外,該行代碼如下錯誤:

echo 'var_dump($f == \'29.85\') = '; 
var_dump($f == 29.85); 

我認爲它應該是:

echo 'var_dump($f == \'29.85\') = '; 
var_dump($f == '29.85'); 
+0

監督,我已經更新了,是的,結果仍是布爾的var_dump(假)($ F == '29 .85'); – kralos

1

當你比較值作爲字符串,雙方都'29.85',讓您得到true。到目前爲止這麼容易。

通過數字值進行比較可將您引導到二進制浮點值表示法的土地。由於數字存儲在base-2中,因此不是可以用表示有限的二進制擴展不能用精確地用浮點數表示。

換句話說,每個不能寫成分母是2的冪的整數部分的數字都不能這樣表示。這包括1/5和1/10和597/20(這是29.85)。

因爲這些數字不能被精確表示,涉及到這樣的數字運算的結果取決於操作的順序和舍入和截斷誤差,因此例如.1 + .1 + .1並不像.3相同,併爲您的計算類似。