ieee754 floating-point computer-science precision programming-fundamentals

IEEE 754 浮動小数点標準:コンピュータ算術の仕組みを理解する

なぜプログラミングで 0.1 + 0.2 != 0.3 なのか?IEEE 754 浮動小数点数の表現方法と精度のメカニズムを詳しく解説します。

2026-04-11

IEEE 754 浮動小数点標準:コンピュータ算術の仕組み

プログラミングをしていると、奇妙な現象に遭遇することがあります。0.1 + 0.20.3 に等しくないのです。代わりに、0.30000000000000004 のような結果が返ってきます。これはプログラミング言語のバグではありません。コンピュータが IEEE 754 標準 を使用して実数を表現する方法から生じる、根本的な結果です。

このガイドでは、IEEE 754 標準を分かりやすく解説し、浮動小数点数がどのように保存されるかを説明し、コード内での精度問題の対処法を紹介します。


IEEE 754 とは何か?

IEEE 浮動小数点数演算標準 (IEEE 754) は、浮動小数点演算において最も広く使用されている標準です。1985 年に策定され、実数をバイナリ(2 進数)で表現する形式と、それらに対する演算を定義しています。

最も一般的な形式は以下の通りです。

  • 単精度 (32ビット): C/C++/Java の float
  • 倍精度 (64ビット): C/C++/Java の double。JavaScript や Python のデフォルトの数値型です。

仕組み:浮動小数点の構造

浮動小数点数は、科学的表記法 ($1.23 \times 10^4$) に似た方法で表現されますが、バイナリ形式です。3 つの部分で構成されています。

  1. 符号ビット (1ビット): 0 は正、 1 は負。
  2. 指数部 (Exponent): 数値のスケールを決定。
  3. 仮数部 (Mantissa/Significand): 有効数字を表現。

64 ビット倍精度レイアウト:

  • 符号: 1 ビット
  • 指数: 11 ビット
  • 仮数: 52 ビット

計算式は以下の通りです。 $(-1)^{sign} \times (1.mantissa) \times 2^{exponent - bias}$


なぜ $0.1 + 0.2 \neq 0.3$ なのか?

根本的な原因は、ほとんどの 10 進小数がバイナリで正確に表現できないことにあります。

  • 10 進法では、分母の素因数が 2 と 5(10 の因数)のみの場合、分数は正確に表現できます。
  • 2 進法では、分母の素因数が 2 のみの場合に限り、分数は正確に表現できます。

$0.1$ は $1/10$ です。10 には因数 5 が含まれるため、バイナリでは無限に繰り返す配列になります。 0.00011001100110011...

コンピュータは、この無限の配列を 32 ビットまたは 64 ビットに収めるために丸める必要があり、その結果、私たちが目にするような微小な誤差が生じます。


特殊な値

IEEE 754 は、例外的なケースを処理するためにいくつかの特殊な値も定義しています。

  • NaN (Not a Number): 不定な演算の結果(例: 0/0)。
  • Infinity ($\infty$): オーバーフローや 0 除算の結果(例: 1/0)。
  • 負のゼロ (-0): 一部の計算で正のゼロと区別されます。

開発者のためのベストプラクティス

  1. 浮動小数点の比較に == を使わない: 常に差が非常に小さい値 (イプシロン) 未満であるかを確認してください。
    if (Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON) { ... }
    
  2. お金の計算には定点数を使う: 財務計算には、専用のライブラリ (例: decimal.js) を使用するか、値を整数(ドルではなくセントなど)として保存してください。
  3. 範囲に注意する: 倍精度は非常に大きな数値を表現できますが、数値が大きくなるほど精度は低下します。

よくある質問 FAQ

Q: 浮動小数点演算は非決定的ですか? A: 一般的には違います。同じ入力と同じ丸めモードが与えられれば、IEEE 754 は同じ結果を生成します。ただし、コンパイラや CPU 命令 (FMA など) によってわずかな差異が生じることがあります。

Q: "BigInt" とは何ですか? A: JavaScript の BigInt は、任意精度の整数を扱います。小数は扱えません。小数が必要な場合は、Decimal ライブラリが必要です。

Q: 倍精度の 10 進精度の桁数は? A: 64 ビット倍精度は、約 15 ~ 17 桁の有効な 10 進数字を持ちます。


関連ツール