JavaScript四捨五入の穴
1799 ワード
前言
JavaScriptを使用して数値を処理するプログラマーは、JavaScriptのNumber.toFixed
をよく知っています.この関数は、数値をフォーマットするときに、自動的に四捨五入されます.たとえば、次のようにします.10.125.toFixed(2) ---> "10.13"
しかし、場合によっては、その四捨五入の結果は、往々にして望ましくないことがあります.例えば、10.145.toFixed(2) ---> "10.14"
では、なぜこのような状況が発生したのか、進数から話す必要があります.
進数の謎
周知のように、コンピュータは設計の初め、各方面の角度から考慮して、最終的にバイナリのフォーマットを採用してデータを格納します.私たちが普段数字に慣用している進数は10進数です.10進数のデータをバイナリ形式で格納すると、必然的に進数の変換に直面し、進数の変換は精度の損失に直面します.
例えば、⅓の場合、3進数では0.1、10進数では0.333(3サイクル)である.それは3つの⅓を加算する場合、3進法では1(3進1に会う)であり、10進法では0.999(9サイクル)である.
同様の場合、10進数と2進数の変換にも現れます.コンピュータでは、変数が10.145であることを宣言しますが、実際には、この数字はバイナリとしてコンピュータに保存されており、本当に10.145ではありません.Number.prototype.toPrecision
の方法で意外を探究することができる.Number.prototype.toPrecision
メソッドは、指定された精度でその数値オブジェクトの文字列表現を返す.10.145.toPrecision(21) ---> "10.1449999999999995737"
したがって、toFixed()
メソッドが返す四捨五入の値が、場合によっては予想に合致しない理由を説明することができる.
同様に、浮動小数点数のすべての計算についても、加減乗除には例外がなく、場合によっては予想に合わない場合があり、最も一般的なのは0.1+0.2
などです.
ソリューション
上記の状況に対して、私は簡単なライブラリを書いて、数字の四捨五入の需要を満たすことができます.round-js
探索浮動小数点数基準
ほとんどの言語とは異なり、JavaScriptは現在、数字の表現について、64ビットの二重精度浮動小数点数を用いて1つの数を表すタイプしかなく、その基準は多くの言語と同様にIEEE-754標準を採用している.IEEE-754の64ビットの二重精度浮動小数点数の基準は、以下のように1枚の図で表すことができる.
10.125.toFixed(2) ---> "10.13"
10.145.toFixed(2) ---> "10.14"
10.145.toPrecision(21) ---> "10.1449999999999995737"
最終的に、任意の数は、この基準に対して、次の式を使用して表されます.
次のようになります.
<1M<2
などの多くの規定があり、詳細は展開されない.終わります.