js計算精度の問題

jsを使用して計算を行う場合、次の問題が頻繁に発生します。

0.1 + 0.2 = 0.30000000000000004
0.3 - 0.2 = 0.09999999999999998
20.123/100 = 0.201230000000000000000002
2.425*100 = 2.424999999999997

IEEE 75464ビットフローティングポイントタイプ
IEEE754

IEEE 754は、浮動小数点値を表す4つの方法を指定しています。単一精度(32ビット)、二重精度(64ビット)、拡張単一精度(43ビット以上、ほとんど使用されない)、および拡張二重精度(79ビット)です。上記は通常80ビットで実装されます)。

この規格の正式名称は、IEEE Binary Floating Point Arithmetic Standard(ANSI / IEEE Std 754-1985)であり、マイクロプロセッサシステムのバイナリ浮動小数点演算であるIEC 60559:1989としても知られています(元の番号はIEC 559:1989です)。
単精度浮動小数点数単精度浮動小数点
数形式は、コンピュータメモリで4ビット(32ビット)を占めるデータタイプです。「浮動小数点」(浮動小数点)法を使用すると、さまざまな値を表現できます。

IEEE 754-2008の定義では、32ビットのベース2フォーマットは正式にはbinary32フォーマットと呼ばれています。この形式は、IEEE 754-1985では単一、つまり単一精度として定義されています。一部の初期のコンピュータシステムでは、他の4バイトの浮動小数点数形式も存在することに注意してください。

定義

最初の桁は正と負を示し、中央の8桁は指数を示し、最後の23桁は有効桁を格納します(有効桁は24桁です)。

真ん中の8ビットは、合計28 = 256の数値を表すことができ、指数は2の補数にすることができます。つまり、0から255、-127から-1の場合は0から126、0の場合は127、1-128の場合は128-255です。

有効桁数の左端の1は存在する必要があるため、保存されません(バイナリの最初の有効桁数は1である必要があります)。つまり、実効桁は24ビットで、実際には23ビットが格納されます。

js計算精度の問題
倍精度浮動小数点数倍精度浮動小数点
数(double)は、コンピューターで使用されるデータ型です。単一精度の浮動小数点数と比較して、倍精度の浮動小数点数(double)は、64ビット(8バイト)を使用して浮動小数点数を格納します。10進法で15桁または16桁の有効桁数を表すことができ、表すことができる数値の絶対値の範囲は約[2.23e-308,1.79e308]です。

定義

単一精度と同様に、最初の桁は正と負を表し、最後の11桁は指数桁、最後の52桁は精度を表します(有効桁は53桁です)。

js計算精度の問題

0.1 /0.2バイナリビット

(0.1).toString(2)=== "0.000 110011001100110011001100110011001100110011001100110 1"

(0.2).toString(2)=== "0.00 1100110011001100110011001100110011001100110011001101"

(0.30000000000000004).toString(2)=== "0.0100110011001100110011001100110011001100110011001101"

(0.3).toString(2)=== "0.010011001100110011001100110011001100110011001100110011"

したがって、バイナリ表現の最後の0.1は0.0001 1001 1001 1001 ...ですが、001101の上の(0.1).toString()の最後の6桁を見ると、通常のサイクルは001100であるはずなので、切り捨て後、0.1バイナリ表現の値は大きくなります。 !0.2をバイナリに変換すると、切り捨て後にも大きくなります。

0.1、0.2のバイナリ表現とそれらの合計を比較すると、文字列の長さは変化しているが、精度は変化していない、つまり1から最後までの文字列の長さは52であることがわかります。

0.1 + 0.2の長さは57である必要がありますが、そのような数値を表すことができないため、1から始まる数値から数えて、最後の3つの数値は切り捨てられます(最終的な精度は52または53です)

2桁を加算すると、0.1 +0.2は
0.01001100 .......... 1100 111合計57、最初の1から54になりますが、最大は53桁であり、切り捨てられます。 52または53になり、その後大きくなります

異なる小数に格納されている最後の桁が異なることに注意してください。

ライブラリを使用して解決し、ライブラリのソリューションを調査するには、特定のソリューションをお勧めします。
より一般的な解決策は、小数を整数に変換してから、小数に戻して解決することです。
math.js bigNumber.jsdecimal.js数値-精度を使用して解決できます

おすすめ

転載: blog.51cto.com/13934921/2569895