精度と誤差

14.2.3. 精度と誤差

浮動小数点表現で表せる数の精度や、特別な値の表現を調べましょう。

精度と範囲 #

64bit のIEEE754 浮動小数点表現は \(\langle s,m,e \rangle\) を使うものでした。

\[x \approx ({-1})^s \underbrace{(1+m \cdot 2^{-52})}_{\text{仮数}} \cdot 2^{\overbrace{(e-1023)}^{\text{指数}}}\]
符号部 \(s\) 指数部 \(e\) 仮数部 \(m\)
符号長 1 ビット 11 ビット 52 ビット

精度は仮数部で決まり 53 ビット、10 進数の 16 桁程度になります。

表現できる絶対値の最大最小値は、指数部が重要です。 指数部 \(e\) の最小値 \(0\) と最大値 \(2^{11}-1\) (全ビット1)は、0 など特殊な値を表現するために予約されています (仮数 \((1+m \cdot 2^{-52})\) は0を表せません)。そのため \(e \in [1,2^{11}-2]\) , \(2^{e-1023}\in[2^{-1022},2^{1023}]\) です。 表そうとした数の 絶対値 が表現範囲の最大値を超えることをオーバーフロー (overflow) と呼び、最小値を下回ることを アンダーフロー (underflow) と呼びます。 オーバーフロー限界は \(2^{1024} \approx 1.8\cdot 10^{308}\) 、アンダーフロー限界は \(2^{-1022} \approx 2.2\cdot 10^{-308}\) になります。

これらの通常の数を、 (あとの非正規化数との対比で) 正規化数 と呼びます。

特別な値 #

指数部 \(e\) の最小値 \(0\) と最大値 \(2^{11}-1\) (全ビット1)は、以下の特別な数を表現します。

種類 Exp(指数部) Fraction(仮数部)
ゼロ 0 0
非正規化数 0 0以外
無限大 2047 0
NaN 2047 0以外の任意
実用上は、 0 以外が表れないように計算を進める方が無難です。
ゼロ
指数部のビットが全て 0 で、仮数部のビットも全て 0 のものとして表現されます。 符号部によって 0 (+0) と −0 の区別があります。 たとえば \(1/0=+\infty\) , \(1/(-0)=-\infty\) と差が生じます。
非正規化数
指数部のビットが全て 0 (つまり \(e=0\) )で、仮数部が 0 以外のものを非正規化数といい、通常の正規化数と 0 の間を表現する数となります。 \[x = ({-1})^s ( m \cdot 2^{-52}) \cdot 2^{-1022}\] 非正規化数の絶対値の最小は \(m=1\) のときで \(2^{-52} \cdot 2^{-1022} \approx 10^{-323}\) となります。非正規化数は計算が遅くなるリスクがあります。
無限大
指数部のビットが全て 1 で、仮数部のビットが全て 0 は無限大です。符号部によって、正負の区別があります。 \(\pm\infty\) に 0 でない有限の数を足しても結果は変わりません。 \(\pm\infty \cdot 0\) \(\infty + (−\infty)\) は次に説明する非数 (NaN) となります。
非数 (NaN)
指数部のビットが全て 1 で、仮数部のビットのどこかが 1 になっているものは非数 (NaN, Not a Number) です。 NaN は、0 / 0 や log(-1) などで発生します。

誤差の拡大 #

有限bit数での表現という制約から、ほとんどの場合に浮動小数点表現は 表現誤差 を伴うことを前ページで紹介しました。 表現誤差自身はとても小さいものですが、この誤差は計算中にさらに拡大することがあります。いくつか例を紹介します。

桁落ち
絶対値の近い数の加減算で、上位の桁が0になり、有効数字が減少することです。 同じ \(e\) \(m\) の上位ビットが揃った異なる数で発生します。10進でも生じます \[ \underbrace{1.231}_{{\text{4桁}}}\underbrace{\text{\_\_\_}}_{\substack{\color{gray}\text{誤}\\\color{gray}\text{差}}} - \underbrace{1.230}_{{\text{4桁}}}\underbrace{\text{\_\_\_}}_{\substack{\color{gray}\text{誤}\\\color{gray}\text{差}}} = \underbrace{0.001}_{{\text{\color{red}{1桁!}}}}\underbrace{\text{\_\_\_}}_{\substack{\color{gray}\text{誤}\\\color{gray}\text{差}}} \] 有効数字が減少した後で、乗算で桁を大きくすると、誤差の絶対値が拡大します。
情報落ち
差の大きな数の加減算で小さな数が無視されることです。 2進 52 桁以上差がある数の加減算で顕著で、 \(2^{-53}\) 自体は正確に表現できるのに、 \(1 + 2^{-53} = 1\) となってしまいます。 情報落ち単独では有効数字を減らしませんが、その後に桁落ちが発生すると誤差が明確になります。
打ち切り誤差
\(\sin, \exp\) などは本質的に近似計算しかできないために生じます。
浮動小数点数 精度と誤差 文書の符号化