2011-11-15 17 views
1

ここに要約:0と仮定し、それを出力php float数学演算のバグ?

演算結果の話

$a = 213480.7-190.46; 
exit($a-213290.24); 
# 2.9103830456734E-11 

結果出力:

$b is : 213480.7 
-190.46 
$b is : 213290.24 

は今のバランスが正しく見えます。しかし、使用時の比較演算子が...結果はここに 奇妙であることのvar_dumpで、

var_dump($b); 
# float 213290.24 

if ($b==213290.24) { 
    exit('same'); 
} elseif ($b>213290.24) { 
    exit('larger '.($b-213290.24)); 
} else { 
    exit('smaller '.($b-213290.24)); 
} 
#larger 2.9103830456734E-11 

誰がどのようにそれを解決するために私に言うことができるの比較結果??

+0

投票停止?わかりません?私の問題ですか? –

+0

私はdownvoteをしませんでしたが、すでにあなたの質問には浮動小数点の精度で答えました。 – deceze

+0

私の問題を特定してくれてありがとう。解決策はありませんか? –

答えて

2

こちらをご覧ください:http://php.net/manual/en/language.types.float.php

をフローティング番号が最後の桁になり、そして決して は平等のための浮動小数点数を比較していない信用しません。より高い精度が である場合、任意の精度の数学関数とgmp関数 が利用可能です。

浮動小数点比較を扱う一般的な方法は、許容可能なεまたは浮動小数点値の差を小さくすることです。許容差が小さいものは同等と見なされます。

if (abs(213290.24 - $b) < .001) { 
    exit('same') 
} 
2

浮動小数点数値で実行される計算では、機械表現の結果として常にinherent errorが返されます。このため、等価演算子==を使用して浮動小数点値を比較しないでください。

一般的なアプローチは、最小許容誤差を決定し、比較したい値の差が所望の誤差より小さいかどうかを確認することです。

$min_error = 0.00001; 
if (abs($a - $b) < $min_error) 
{ 
    exit("same"); 
} 
0

これは、それがバイナリフロートの自然と接続して、PHPの問題ではありません。 すべての有理数をfloatで正確に表すことはできません。たとえば、0.1 + 0.2 == 0.3を比較しようとすると、0.3が正確に表現されないため、失敗することになります。