IEEE 754のマシンイプシロンとULP

マシンイプシロン(1.0と次の表現可能な浮動小数点数の間のギャップ)とULP(最下位の単位)を理解。数値解析と誤差の限界に不可欠。

Precision

Decimal Value

2.220446049250313e-16

Float32 Hex

0x34000000

Float64 Hex

0x3CB0000000000000

詳細な説明

マシンイプシロンは、利用可能な精度の最も細かい粒度を数値化する浮動小数点演算の基本定数です。浮動小数点演算で1.0 + e > 1.0となる最小の値eとして定義されます。

マシンイプシロンの値:

精度 マシンイプシロン Hex
Float32 2^-23 ≈ 1.192e-7 0x34000000
Float64 2^-52 ≈ 2.220e-16 0x3CB0000000000000

なぜこの特定の値か?

Float64は52ビットの仮数を持ちます。値1.0は1.000...0(バイナリポイントの後に52個のゼロ)として格納されます。次の表現可能な数は1.000...01(51個のゼロの後に1)で、これは1 + 2^-52に等しいです。したがって、1.0と次の浮動小数点数の間のギャップは2^-52です。

ULP — 最下位の単位:

マシンイプシロンは1.0でのギャップを測定しますが、ULPは任意の値でのギャップを測定します。数値xのULPは、xの大きさでの最下位仮数ビットの値です。

指数eを持つfloat64値xの場合: ULP(x) = 2^(e - 52)

例:

  • x = 1.0(指数0): ULP = 2^-52 ≈ 2.22e-16
  • x = 1024.0(指数10): ULP = 2^-42 ≈ 2.27e-13
  • x = 1e15(指数 約49): ULP = 2^-3 = 0.125

実用的な意味:

数値が大きくなると、隣接する表現可能な値の間のギャップが大きくなります。1e15では整数を正確に表現できません — 隣接値の間のギャップは0.125です。2^53では連続する整数が2離れています。これがJavaScriptでNumber.MAX_SAFE_INTEGER = 2^53 - 1である理由です。

比較にイプシロンを使用する:

単純なイプシロン比較は1.0付近で機能します:

Math.abs(a - b) < Number.EPSILON

しかし、大きな値にはスケーリングされたイプシロンが必要です:

Math.abs(a - b) < Math.max(Math.abs(a), Math.abs(b)) * Number.EPSILON * factor

factorは浮動小数点演算がどれだけ誤差を蓄積したかに依存します。良く条件付けられたアルゴリズムの典型的な係数は4〜16です。

Kahan総和と誤差:

数値解析では、マシンイプシロンは蓄積誤差の限界を計算するために使用されます。Kahan総和は、例えば、素朴な加算がO(n * epsilon)の誤差を蓄積するのに対し、加算の回数に関係なくepsilonに比例する誤差を達成します。

ユースケース

マシンイプシロンは、誤差限界の計算、反復アルゴリズムの収束基準の実装、堅牢な浮動小数点比較の設計、および金融や科学アプリケーションにおける倍精度演算の限界の理解において、数値解析に不可欠です。

試してみる — IEEE 754 Inspector

フルツールを開く