2012-05-12 14 views
0

可能性の重複:
Is JavaScript's Math broken?Javascriptを:精密奇妙な行動

と仮定、

var x = .6 - .5; 

var y = 10.2 – 10.1; 

var z = .2 - .1; 

比較結果

x == y;  // false 

x == .1; // false 

y == .1; // false 

しかし

z == .1; // true 

なぜJavascriptのショーな行動?

+2

最初の2つの比較は少し奇妙です。なぜあなたはそれらが一致すると思いますか? (-0.1対0.1) – Mat

+0

関連項目:http://stackoverflow.com/questions/1458633/elegant-workaround-for-javascript-floating-point-number-problem – BasTaller

答えて

6

浮動小数点は完全に正確ではないためです。あなたはとわずかにの違いで終わることができます。

(サイドノート:私はあなたがそうでなければ、あなたは0.1-0.1を比較しているvar x = .6 - .5;を意味だと思う)

JavaScriptがIEEE-754倍精度64ビット浮動小数点(ref)を使用しています。これはと非常に良い浮動小数点数の近似ですが、すべての浮動小数点数を2進数で表す完全な方法はありません。

いくつかの不一致は、他の不一致よりも見やすいものです。例えば:

console.log(0.1 + 0.2); // "0.30000000000000004" 

C#のdecimalタイプまたはJavaのBigDecimal a'la「小数」のことを行うそこにいくつかのJavaScriptライブラリがあります。これは実際には数値が10進数の列として格納される場所です。しかし、それらは万能薬ではなく、さまざまな種類の問題を抱えています(たとえば、1/3を正確に表現しようとします)。私たちは財務的なものに必要な丸めのスタイルに対処するので、 "小数"型/ライブラリは金融アプリケーションにとって素晴らしいですが、IEEE浮動小数点よりも遅い傾向があります。

レッツ・出力あなたのxy値:

var x = .6 - .5; 
console.log(x); // "0.09999999999999998" 

var y = 10.2 - 10.1; 
console.log(y); // "0.09999999999999964" 

ない大きな驚き0.099999999999999980.09999999999999964から!=であること。:-)

あなたは比較動作させるために、これらのビットを合理化することができます

function roundTwoPlaces(num) { 
    return Math.round(num * 100)/100; 
} 

var x = roundTwoPlaces(0.6 - 0.5); 

var y = roundTwoPlaces(10.2 - 10.1); 

console.log(x);  // "0.1" 
console.log(y);  // "0.1" 
console.log(x === y); // "true" 

以上の一般的な解決策:

function round(num, places) { 
    var mult = Math.pow(10, places); 
    return Math.round(num * mult)/mult; 
} 

Live exampleを| source

精度の低下が結果として得られる数値になる可能性があることに注意してください。ただし、同じ数の数字でroundを実行すると、非常に近い非常に近い2つの数値は終了する必要があります(たとえその数字が完全に正確ではないとしても)同じ数字である。

+0

JavaScriptの浮動小数点数の精度を考慮しないでください。 。=)) – benqus

+0

@benqus:Enh、ほとんどの目的には十分です。 JavaScriptだけではないことを忘れないでください。多くのシステムでは、IEEE-754が使用されています。 –

+0

最後のトリックは面白い仲間です!私は、標準JSが何を使用していてもそれは狂っていることを意味します。 =)あなたが気にしないなら、私はこの解決法を保存します。これは小さな数字でも動作しますか?0.00245? – benqus