JSインタビュー----なぜ0.1 + 0.2!= 0.3なのか?この問題を解決する方法

0.1 + 0.2!= 0.3?

最初に例を見てみましょう

console.log(0.1 + 0.2)   // 結果は0.3ではありません0.30000000000000004 0.3 
console.log(0.2-0.1 )// 0.1

これはなぜですか?

この問題の原因を理解するには、まずコンピューターで数値がどのように保存および計算されるかを理解する必要があります。コンピュータでは、固定小数点数と浮動小数点数の両方がマルチビットのバイナリ形式で格納されます。JSではIEEE 754の倍精度バージョン(64ビット)を使用しているため、IEEE 754の言語を使用している限り、この問題が発生します。ストレージ構造を簡単に見てみましょう。

IEEE 754倍精度(64ビット)浮動小数点数の構造:

それらの中で:

名前長さビット位置

符号(S)1ビット(b63)

指数(E)11ビット(b62-b52)

仮数(M)52ビット(b51-b0)

デュアルプログレスの指数部(E)で使用されるオフセットコードは1023です

評価方法:(-1)^ s *(1.M)* 2 ^(E-1023)

JSでの0.1の表現

なぜ0.1がバイナリであるのかを見てみましょう

// 0.1バイナリ(0011)はサイクルを意味します 
0.1 = 0.0001100110011(0011  0.1 = 2 ^ -4 * 1.10011(0011)

0.1は2進数の無限ループの数であり、実際には0.1を超えています。10進数の多くは、2進数で無限にループしています。これは実際には問題ありませんが、JSによって採用された浮動小数点標準は私たちの数値を切り捨てます。つまり、IEEE 754の下位桁が52ビットを超えると、ループされた0011が切り捨てられ、精度が低下するという問題が発生します。それは0.1 もはや  それが原因であった  0.1 が、となった 0.100000000000000002

0.100000000000000002 === 0.1 // true

次に、同じように0.2 、バイナリでは無限ループでもあり、カット後も精度が失われ、 0.200000000000000002

0.200000000000000002 === 0.2 // true

したがって、これら2つの合計は等しくありません  0.3 が、 0.300000000000000004

0.1 + 0.2 === 0.30000000000000004 // true

0.1が0.1でない場合、なぜconsole.log(0.1)が正しいのですか?

内容を入力すると、2進数が10進数に変換され、10進数が文字列に変換されるため、この変換処理では近似処理が行われるため、実際に出力されるのは近似値です。ネイティブな方法は、toFixed()メソッドを使用することです。

 0.1 + 0.2の問題を解決!= 0.3

0.1 + 0.2を解く方法!= 0.3はネイティブの方法を使用することです

parseFloat((0.1 + 0.2).toFixed(10))=== 0.3 // true

ES 6では、非常に小さな定数、Number.EPSILONがNumberオブジェクトに追加されました。この最小定数を導入する目的は、2つの数値間の誤差がNumberより小さい場合に、浮動小数点計算の誤差範囲を設定することです。 EPSILON、2つの数値は等しいと思います。

0.1 + 0.2-0.3 <Number.EPSILON // true

 

おすすめ

転載: www.cnblogs.com/jett-woo/p/12566682.html