2016-11-03 4 views
1

私のコードでは奇妙なことが起こっています。誰かがなぜこの状態が間違っているのか説明できますか?この条件はなぜ偽ですか?

PHPの機能var_dump()とI出力オブジェクトのメンバーは、私はこれを取得:一つのオブジェクトから

string(6) "105.63" 
float(105.63) 

を、これは別のオブジェクトから出力された:

string(6) "667.69" 
float(667.69) 

それから私はこのような比較を行います:

if(105.63 == "105.63"){ 
    echo "true";  
} else { 
    echo "false"; 
} 
if(667.69 == "667.69"){ 
    echo "true"; 
} else { 
    echo "false"; 
} 

2回出力true f上記の私の例のようなコードを書いているかどうかは確かです。しかし、私のクラスでは、それは異なって振る舞います。最初にifで私はfalseを得て、次にiftrueを得る。それから私はvar_export()機能をより深くデータを見て、私は実際にデータを以下しているように思える:

'105.63' 
105.6300000000000096633812063373625278472900390625 

'667.69' 
667.69000000000005456968210637569427490234375 

をだから私は私の条件は、そのデータを扱う天気をチェックすることを決定しました。..彼らはいない。実際は、最初のものだけがそうではありません。次のコードで出力がfalsetrueになるのはなぜですか?

if(105.6300000000000096633812063373625278472900390625 == "105.63"){ 
    echo "true";  
} else { 
    echo "false"; 
} 
if(667.69000000000005456968210637569427490234375 == "667.69"){ 
    echo "true"; 
} else { 
    echo "false"; 
} 

これを解決する方法はわかりました。しかし、なぜ最初に条件が満たされないのか興味がありますif。 PHPは、我々は==比較演算子を使用するときにジャグリングを入力し

EDIT

! これを見てください:

var_export((float) "105.63"); 
var_export((string) 105.6300000000000096633812063373625278472900390625); 
var_export((float) "667.69"); 
var_export((string) 667.69000000000005456968210637569427490234375); 

出力:

105.63 
'105.63' 
667.69000000000005 
'667.69' 

はこれが最初の条件が真であることを意味し、二偽のではないでしょうか?しかし、私は最初に偽になり、2番目に真実になります。私が不明な場合は申し訳ありません。

+2

[浮動小数点表現(https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems) –

+0

有限の紙を使用するシステムでは、バイナリに同じ問題があります。浮動小数点に対して '=='を使用しないで、代わりに '$ epsilon'が任意の小さな定数(精度)である' abs($ number- $ otherNumber)<$ epsilon'を使用してください。 – apokryfos

+0

私の編集をチェックしてください。 – ksno

答えて

3

マニュアルを参照してください:http://php.net/manual/en/language.types.float.php

浮動小数点数を比較に関する大きな警告セクションがあります:

WARNING

浮動小数点数が限られている

浮動小数点精度

は、精度。それは システムに依存しますが、PHPは通常、 1.11e-16の順番で四捨五入されるため、最大相対誤差を与えるIEEE 754倍精度形式、 を使用します。0以外の算術演算は、 の誤差を大きくし、 いくつかの演算を複合したときにエラー伝播を考慮する必要があります。さらに の有理数は、 0.1または0.7のように、基底10の浮動小数点数として正確に表現できますが、 の仮数にかかわらず、内部で使用される2の浮動小数点数として正確な表現はありません。したがって、それらは精度のわずかな損失なしで内部のバイナリ の対応するものに変換することはできません。 は、内部表現 が7.9999999999999991118のようなものになるので、 は、予想される8の代わりに7を返します。 のように、floor((0.1 + 0.7)* 10)は通常 を返します。浮動小数点の結果が最後の桁になり、浮動小数点の の浮動小数点数を直接比較しないでください。より高い精度が必要な場合は、 任意精度の数学関数とgmp関数は です。 「シンプルな」説明については、「浮動小数点ガイド 」を参照してください。「マイナンバーを追加しないのはなぜですか?」もし比率を表すことができない同じ理由1/3小数にするため

Why dont my numbers add up?

+0

私の編集をチェックしてください。 – ksno

関連する問題