2011-09-30 17 views
6

可能性の重複:次のコードの結果がどうなるか
Is JavaScript's Math broken?
Why can't decimal numbers be represented exactly in binary?合計:奇妙な行動

if(0.3 == (0.1 + 0.1 + 0.1)) 
{ 
     alert(true); 
} 
else 
{ 
     alert(false); 
} 

それは奇妙です、結果は偽になります。

理由

0.1 + 0.1 + 0.1

の結果は、この動作を説明することができますか

0.30000000000000004

でしょうか?ありますか

+2

http://stackoverflow.com/questions/1089018/why-cant-decimal-numbers-be-represented-exactly-in-binary – mtrw

+1

さらに詳しくはJavaScriptのhttp://stackoverflow.com/questionsをご覧ください。/4088590/0-43-in-javascript-not-1-2-its-1-20000000002-what-happening –

+2

おそらく、FAQや検索のアドバイスに従ってから、 。 – paxdiablo

答えて

2

を読んでそれは1/3 + 1/3 + 1/3はあなたに正確に1小数では得られないことがあり、同じ理由です。 1/33を.33333333として使用すると、1/3 + 1/3 + 1/3.9999999となりますが、それはちょうど1ではありません。

あなたが行っていることを正確に把握していない限り、非整数の数値型と等しいかどうかを比較しないでください。

1

これは、コンピュータに格納されているフロートの性質によるものです。任意の浮動小数点数を格納する正確な方法はありません。

function equals(f1, f2){ 
    var epsilon = 0.00001; //arbitrary choice 
    return (f1-f2 < epsilon && f2-f1 < epsilon); 
} 

ので、あなたの場合、変化(0.3 ==(0.1 + 0.1 + 0.1)場合:あなたは山車を比較するときには、一般的にやっていることの違いはこのように、いくつかの小さな数イプシロンより小さいかどうかを確認することです)to(等号0.3、(0.1 + 0.1 + 0.1))

1

あなたが経験しているのは、基本的な浮動小数点丸め誤差です。

2進数の性質上、何らかの誤差がない限り正確に0.1を表すことはできません。 WolframAlpha reports小数点以下0.1〜2進数0.00011001100110011 ... 2進数表記でどのように表現できないのでしょうか?これは、この数値の計算をやめるためのカットオフポイントを決める必要があることを意味します。それ以外の場合は、永遠にここにいます。

これはエラーを引き起こします。そして、このエラーは、コードが数字を加算するときに蓄積されます。その結果、あなたの合計の最後に信じられないほど少量が追加されます。これにより、合計が正確に0.3になることはありません。これはIFテストが探しているものです。

ただし、10進数の中には、dec 0.5 = bin 0.1、dec 0.25 = bin 0.01などの2進数で正確に表すことができます。 012 =(0.25 + 0.25)を使用して元のコードと同様に

We can demonstrate thisとなります。


この詳細については、The Floating-Point Guideをお読みください。

浮動小数点数の概念と、計算のエラーがどのように発生するかをよく理解しています。 Javascriptには、発生している丸め誤差を克服する方法を示すセクションもあります。