0.1 + 0.2 とは何ですか?きょとんとした顔をされても構いません 0.1 + 0.2 = 0.3 ああ、まだ聞きますか?このような小児科の質問には幼稚園児でも答えることができます。しかし、ご存知のように、プログラミング言語における同じ問題は、想像されているほど単純ではない可能性があります。
信じられないですか?まず JS の一部を見てみましょう。
var numA = 0.1;
var numB = 0.2;
アラート( (数値 A + 数値 B) === 0.3 );
実行結果は false になります。はい、初めてこのコードを見たときは、当然のことだと思いましたが、実行結果を見て驚きました。私の開き方が間違っていたのでしょうか。いいえ、いいえ。次のコードをもう一度実行してみましょう。結果が false になる理由がわかります。
var numA = 0.1;
var numB = 0.2;
アラート(numA + numB);
0.1 + 0.2 = 0.30000000000000004 であることがわかります。おかしくないですか?実際、浮動小数点数の四則演算では、ほとんどすべてのプログラミング言語で精度エラーと同様の問題が発生しますが、C++/C#/Java などの言語では、精度の問題を回避するためにメソッドがカプセル化されています。 JavaScript は弱い型であるため、設計の観点からは浮動小数点数に対する厳密なデータ型が存在しないため、精度誤差の問題が特に顕著になります。この精度エラーが発生する理由とその修正方法を分析してみましょう。
まず、0.1 + 0.2 という一見小児的な問題をコンピューターの観点から考えなければなりません。コンピューターが読み取ることができるのは 10 進数ではなく 2 進数であることはわかっているので、まず 0.1 と 0.2 を 2 進数に変換して見てみましょう。
0.1 => 0.0001 1001 1001 1001… (無限ループ)
0.2 => 0.0011 0011 0011 0011… (無限ループ)
倍精度浮動小数点数の小数部は最大 52 ビットをサポートするため、2 つを加算すると、0.0100110011001100110011001100110011001100110011001100 という文字列が得られます。浮動小数点数の小数点以下の制限により2進数は切り捨てられますが、このとき10進数に変換すると0.30000000000000004となります。
それで、この問題を解決するにはどうすればよいでしょうか?私が望む結果は 0.1 + 0.2 === 0.3 ああ! ! !
最も簡単な解決策の 1 つは、値を返すプロセス中に、次のような明確な精度要件を指定することです。
var numA = 0.1;
var numB = 0.2;
alert( parseFloat((numA + numB).toFixed(2)) === 0.3 );
しかし、明らかに、これは一度限りの方法ではありません。これらの浮動小数点数の精度の問題を解決できる方法があれば素晴らしいでしょう。この方法を試してみましょう:
Math.formatFloat = function(f, digit) {
var m = Math.pow(10, digit);
return parseInt(f * m, 10) / m;
}
var numA = 0.1;
var numB = 0.2;
alert(Math.formatFloat(numA + numB, 1) === 0.3);
この方法は何を意味するのでしょうか?精度の差を避けるためには、計算する数値に10のn乗を掛け、コンピュータが正確に認識できる整数に変換してから、10のn乗で割る必要があります。プログラミング言語は精度の違いを処理します。これを使用して、JS の浮動小数点数の精度エラーを処理します。
次回、誰かが 0.1 + 0.2 は何に等しいかを尋ねたら、答えには注意する必要があります。 !