重複の可能性:
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はそのような振る舞いをするのですか?
重複の可能性:
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はそのような振る舞いをするのですか?
浮動小数点は完全に正確ではないためです。わずかな違いが生じる可能性があります。
(補足:var x = .6 - .5;
それ以外の場合は、と比較-0.1
していると思います0.1
。)
JavaScriptは、IEEE-754倍精度64ビット浮動小数点(ref)を使用します。これは浮動小数点数の非常に優れた近似ですが、すべての浮動小数点数を2進数で表す完全な方法はありません。
一部の不一致は、他の不一致よりも見やすくなっています。例えば:
console.log(0.1 + 0.2); // "0.30000000000000004"
decimal
「10進数」のことを「C#」タイプまたは「Java 」タイプで実行するJavaScriptライブラリがいくつかありますBigDecimal
。ここに、数値が実際に一連の10進数として格納されます。しかし、それらは万能薬ではなく、異なるクラスの問題を抱えているだけです(1 / 3
たとえば、正確に表現するようにしてください)。「10進数」タイプ/ライブラリは、金融関連で必要な丸めのスタイルを処理することに慣れているため、金融アプリケーションには最適ですが、IEEE浮動小数点よりも遅くなる傾向があるというコストがあります。
x
あなたとy
値を出力しましょう:
var x = .6 - .5;
console.log(x); // "0.09999999999999998"
var y = 10.2 - 10.1;
console.log(y); // "0.09999999999999964"
それは大きな驚きで0.09999999999999998
はあり!=
ません0.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;
}
round
結果の数値に精度のクラッドが含まれる可能性はありますが、同じ数の場所で実行された場合、互いに非常に非常に近い少なくとも2つの数値は、同じ数になるはずです(その数が完全に正確でなくても)。