分析します
JavaScriptの数字は1つしかなく、JavaScriptのすべての数値はIEEE-754標準形式で表されます。 いくつかの小数はバイナリの無限の数字を表すため、浮動小数点数の精度の問題はJavaScriptに固有のものではありません。
10進バイナリ
0.1 0.0001 1001 1001 1001 ...
0.2 0.0011 0011 0011 0011 ...
0.3 0.0100 1100 1100 1100 ...
0.4 0.0110 0110 0110 0110 ...
0.5 0.1
0.6 0.1001 1001 1001 1001 ...
したがって、1.1、そのプログラムは実際に「1.1」を表すことはできませんが、これは正確さの避けられない損失しか達成できません。
1.0999999999999999999
JavaScriptの問題はより複雑です。ここにChromeのテストデータのみがあります。
入出力
1.0-0.9 == 0.1 False
1.0-0.8 == 0.2 False
1.0-0.7 == 0.3 False
1.0-0.6 == 0.4 True
1.0-0.5 == 0.5 True
1.0-0.4 == 0.6 True
1.0-0.3 == 0.7 True
1.0-0.2 == 0.8 True
1.0-0.1 == 0.9 True
解決する
では、1.0-0.9!= 0.1でこのタイプの非バグ問題を回避するにはどうすればよいですか?現在、より頻繁に使用されるソリューションがあります。
コードコピーは次のとおりです。
(1.0-0.9).tofixed(digits)// tofixed()精度パラメーターは0〜20でなければなりません
parsefloat((1.0-0.9).tofixed(10))=== 0.1 //結果は真です
parsefloat((1.0-0.8).tofixed(10))=== 0.2 //結果は真です
parsefloat((1.0-0.7).tofixed(10))=== 0.3 //結果は真です
parsefloat((11.0-11.8).tofixed(10))=== -0.8 //結果は真です
メソッド精製
コードコピーは次のとおりです。
// Isequal Toolメソッドを使用して、値が等しいかどうかを判断します
関数isequal(number1、number2、桁){
数字= ==未定?
return number1.tofixed(digits)=== number2.tofixed(digits);
}
ISEQUAL(1.0-0.7、0.3);
//ネイティブ拡張法、オブジェクト指向のスタイルを好みます
number.prototype.isequal = function(number、digits){
数字= ==未定?
this.tofixed(digits)=== number.tofixed(digits)を返します。
}
(1.0-0.7).isequal(0.3);