javascriptデジタル計算精度誤差を避ける方法詳細


もしあなたに0.1+0.2はいくつですか?白い目で見てくれるかもしれませんが、0.1+0.2=0.3です。幼稚園の子供でさえ、このような小児科の問題に答えられます。でも、知っていますか?同じ問題はプログラミング言語において、想像の中でそんなに簡単なことではないかもしれません。信じない?まずJSを見に来ます。
var numA=0.1var numB=0.2alert((numA+numB)==0.3)
実行結果はfalseです。そうです。このコードを初めて見た時、私ももちろんtrueだと思いましたが、実行結果によってメガネを落としました。私の開け方が正しいですか?非も非もない。私たちは次のコードを実行してみます。結果はどうしてfalseなのか分かります。
var numA=0.1var numB=0.2alert(numA+numB)
もとは0.1+0.2=0.3000万0004だった。変ですか?浮動小数点数の四則演算については、ほとんどのプログラミング言語に類似の精度誤差があります。C+++/C((zhi/Java)という言語には精度の問題を回避するための方法がカプセル化されています。JavaScriptは弱いタイプの言語です。デザイン思想から浮動小数点に対して厳密なデータタイプはありません。精度誤差の問題は特に顕著である。なぜこの精度誤差があるのか、どのように誤差を修復するのかを分析します。
まず、私たちはコンピュータの角度に立って、0.1+0.2という小児科のような問題を考えます。コンピュータで読めるのはバイナリで、十進法ではないことを知っていますので、まず0.1と0.2をバイナリに変えてみます。
0.1=>0.0001 1001 1001…(無限ループ)0.2=>0.0011 0011 0011…(無限ループ)
ダブル精度浮動小数部は最大52桁まで対応していますので、このように0.0100110011001100110010010001011001000110010010001100の浮動小数点数の制限で切り捨てられたバイナリ数字を2列加算した後、10進数に変換すると0.3000万0004になります。
なるほど、この問題はどう解決しますか?欲しい結果は0.1+0.2==0.3です。
一番簡単な解決策があります。正確な精度要求を与えます。戻り値の過程で、コンピュータは自動的に四捨五入します。
var numA=0.1var numB=0.2alert(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.1var numB=0.2
alert(Math.formatFloat(numA+numB、1)==0.3)
この方法はどういう意味ですか?精度の違いを避けるために、計算が必要な数字を10のn乗に掛け、計算機で正確に識別できる整数に換算して、さらに10のn乗を割ります。ほとんどのプログラミング言語はこのように処理精度の差があります。JSにおける浮動小数点の精度誤差を処理します。
今度また誰かに聞いたら、0.1+0.2は何ですか?気をつけて答えてください。