2011-12-07 75 views
1

我將兩個數字字符串$ a和$ b加在一起,然後將結果與另一個數字字符串$ c進行比較。所有這三個數字都存儲爲字符串,並在比較步驟中通過PHP轉換爲浮點數。在PHP中奇怪的加入數字字符串

出於某些原因,測試$ a + $ b == $ c不會評估爲true,即使它應該。

您可以重新使用這個腳本的問題:

<?php 
$a = "-111.11"; 
$b = "-22.22"; 
$c = "-133.33"; 

echo '$a is '.$a."\n"; 
echo '$b is '.$b."\n"; 
echo '$c is '.$c."\n"; 
echo '$a + $b is '.($a+$b). "\n"; 

if ($a + $b == $c) { 
    echo 'a + b equals c'."\n"; 
} else { 
    echo 'a + b does not equal c'."\n"; 
} 
?> 

古怪,如果我改變的值略有使得$ A = -111.11,$ B = -22.23和$ C = -133.34它按預期工作。

我是否缺少明顯的東西,或者這是PHP的錯誤?

+1

http://php.net/manual/en/language.types.float.php – Shad

+2

浮動有限的精度。一旦你引入第一個浮點數,你就會失去準確性。因此比較無效。 – mario

+1

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Corbin

回答

2

您正遇到浮點運算的限制。正如有些數字不能完全用十進制表示(例如1/3),所以有些數字不能完全用浮點數表示。

您不應該嘗試比較浮點數是否相等,因爲浮點的限制使得您正在比較的變量的實際值不可能與您認爲具有的值完全匹配。你需要添加一個「模糊因素」,也就是說如果兩個數字在一定的容差範圍內相似,那麼你應該認爲它們是相等的。

您可以通過從另一箇中減去一個數,看是否絕對結果低於您的門檻做到這一點(在我的例子,0.01):

if (abs ($someFloatingPointNumber - $someOtherFloatingPointNumber) <= 0.01) 
{ 
    // The values are close enough to be considered equal 
} 

當然,這與舍入誤差相結合,可以蠕變在連續的數學運算中意味着浮點數通常不是最好的選擇,應儘可能地避免。例如,如果您要處理貨幣,請將您的值作爲整數存儲在次要單位中(便士爲英鎊,美元爲美元等),並且只能將主要單位除以100以顯示。

+0

感謝您的回答。這是我最終使用的解決方案。 –

5

從這個頁面上的大紅色框:http://php.net/manual/en/language.types.float.php

從來沒有比較浮點數是否相等。

基本上,你沒有得到正確的數字,因爲它們以一種稍微不同的格式保存,所以當你比較時,它會被搞砸。

這@Corbin的鏈接是非常好的,所以我將它只是爲愛:)
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

什麼每臺計算機科學家應該知道關於浮點運算

本文介紹了一個關於浮點的教程,它們對計算機系統的設計者有直接的影響。它始於 浮點表示和四捨五入誤差的背景, 繼續討論IEEE浮點標準, 總結了許多計算機制造商可以更好地支持浮點的示例。

1

你的號碼總是有兩位小數位嗎?

如果是的話,你可以試試這個:

$aDec = round($a * 100); 
$bDec = round($b * 100); 
$cDec = round($c * 100); 

if ($aDec + $bDec == $cDec) { 
    ... 
} 
+0

是的,他們只有2個小數點,因爲他們是貨幣金額。我會放棄這一點。 –