2012-03-03 90 views
1

可能重複:
Strange addition of numeric strings in PHP奇怪的行爲

$r = 1.0 - 0.8 - 0.2; 
var_dump($r); 

我得到浮動-5.5511151231258E-17。 我在C++和C#中獲得的結果相同。

的MySQL我得到通過查詢產生的0.0:

SELECT 1.0 - 0.8 - 0.2 
+0

*一般參考的問題* http://php.net/manual/en/language.types.float.php – NikiC 2012-03-03 14:28:33

+0

另外:HTTP://en.wikipedia。組織/維基/ Floating_point#Accuracy_problems – Leigh 2012-03-03 14:33:12

回答

8

讓它成爲明確:0.8在十進制有限表示,因爲它的價值8/10¹

但在基數2中,其值爲:1/2 + 1/4 + 0/8 + 0/16 + 1/32 + 1/64 + 0/128 + ...並且它沒有結束,像三分之一具有十進制表示(0.333…)沒有結束,但將在0.1基座3

0.8 = 0.110011001100110011001100... in binary 
0.2 = 0.001100110011001100110011... in binary 

筆記本計算機存儲浮點值的二進制表示。因此,當您添加,減去,乘數等數字時,會出現精度損失。

C++,C和C#是編譯語言,浮點數通常是4或8字節。你不能將0.8存儲在浮動中。

MySQL可能會告訴你0,因爲它會截斷計算結果。

如果您想要一個在任何基礎上執行計算而不損失精度的庫,請查找GMPlib。

3

您可以通過使用BCMath(此例爲bcsub())來避免它。或者你可以簡單地round()(注意你可以設置第二個參數的精度)。對於所有情況下,您將收到-0,如果您需要積極0只使用abs()

看看我說的here

代碼示例

<?php 

    echo 'Direct: ' . (1.0 - 0.8 - 0.2) . '<br/>'; 

    echo 'BC Math: ' . bcsub(bcsub('1.0', '0.8'), '0.2') . '<br/>'; 
    echo 'Round: ' . round(1.0 - 0.8 - 0.2) . '<br/>'; 
    echo 'Absolute: ' . abs(round(1.0 - 0.8 - 0.2)) . '<br/>'; 

?>