JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptの浮動小数点演算は100%正確か?丸め誤差の原因と具体例を解説

JavaScriptの浮動小数点演算は100%正確なのか?

結論から言うと、JavaScriptの浮動小数点演算は必ずしも100%正確ではありません。その理由を理解するために、「1/3」という例を考えてみましょう。1/3を小数で表すと 0.33333… となり、どこかの時点で値が丸められます。この丸められた値に別の小数を加算すると、期待通りの結果にならないことがあります。

つまり、小数同士の演算では「丸め誤差」が発生するということです。幸い、この誤差は非常に小さいため、実際のコードの結果に大きな影響を与えることはほとんどありません。

なぜ丸め誤差が発生するのか

JavaScriptは数値をIEEE 754倍精度浮動小数点形式で扱っています。この形式では数値を2進数で表現するため、10進数ではきれいに書ける「0.1」や「0.3」のような値も、2進数では無限小数となり、近似的な値として格納されます。この近似のずれが、計算結果に丸め誤差として現れるのです。

例1:0.3 + 0.6 の場合

次の例では、0.3 に 0.6 を足すため、本来なら結果は 0.9 になるはずです。しかし丸め誤差の影響により、出力結果のように意図した値にはなりません。

サンプルコード

<html>
<body>
  <p id="F-P-A"></p>
  <script>
    var err = 0.3 + 0.6;
    document.getElementById("F-P-A").innerHTML = "0.3 + 0.6 = " + err;
  </script>
</body>
</html>

実行結果

0.3 + 0.6 = 0.8999999999999999


例2:0.2 + 0.1 の場合

もう一つの例として、0.2 と 0.1 を加算すると、期待される結果は 0.3 ですが、丸め誤差のために意図した値にはなりません。

サンプルコード

<html>
<body>
  <p id="F-P-A"></p>
  <script>
    var err = 0.2 + 0.1;
    document.getElementById("F-P-A").innerHTML = "0.2 + 0.1 = " + err;
  </script>
</body>
</html>

実行結果

0.2 + 0.1 = 0.30000000000000004


まとめ

JavaScriptにおける浮動小数点演算は、仕組み上どうしても微小な丸め誤差を含みます。金額計算など高い精度が求められる場面では、値を一度整数に変換してから計算する、toFixed()メソッドで桁数を揃える、あるいは誤差処理に対応した専用ライブラリを利用するなどの対策を行うと安全です。

  1. JavaScriptのPromise(プロミス)とは?非同期処理の基本と使い方を解説

    JavaScriptのPromise(プロミス)は、作成された時点ではまだ値が確定していない非同期処理を扱うためのオブジェクトです。APIリクエストやファイルの読み込みなど、完了まで時間がかかる処理について、「いずれ結果を受け取る」という約束を表現します。Promiseは、以下の3つの状態を持ちます。pending(保留中):処理がまだ完了しておらず、成功も失敗も確定していない初期状態fulfilled(履行済み):処理が正常に完了し、結果の値が利用できる状態rejected(拒否済み):処理が失敗し、エラーの理由が利用できる状態一度fulfilledまたはrejectedに遷移したPromi

  2. JavaScriptのWeakSetとは?特徴と主要メソッド、サンプルコードをわかりやすく解説

    JavaScriptのWeakSet(ウィークセット)は、オブジェクトを格納するためのコレクションです。Setと同様に、同じオブジェクトを重複して保存することはできません。WeakSetの主な特徴弱い参照で保持する:WeakSet内のオブジェクトへの参照が他に存在しなくなると、ガベージコレクションによって自動的にメモリから解放されます。そのため、メモリリークを防ぎたい場面で役立ちます。オブジェクトのみ格納可能:数値や文字列などのプリミティブ値は追加できません。列挙できない:Setのようなsizeプロパティや反復処理の仕組みを持たず、格納されている要素の一覧を取得することはできません。WeakS