浮動小数点数の丸め誤差と誤差伝搬

Last updated:

浮動小数点数を使った数値計算では、数値の変換や演算のたびに丸め誤差が発生する。 特に複数回演算操作を行った後、誤差がどう伝搬していくかは、直感的には分かりにくい問題だ。 この記事では、IEEE 754-2019をもとに浮動小数点数の定義を確認し、誤差推定の基本的な方法について議論していこう。

浮動小数点の仕組み

まず、浮動小数点数には大きく2つのタイプ、バイナリ浮動小数点とデシマル浮動小数点が存在する。 この記事では、コンピュータ上で実数を表現する際に一般的に使用されるバイナリ浮動小数点に焦点を当てて議論を進める。

浮動小数点数の基本的なコンセプトは次のように説明できる。

  • Sign bit(1ビットデータ)はその値の正負を表す。
  • Exponent bitsは2e2^eの形で2のべき乗を表す。
  • Significand bitsは2e2^e2e+12^{e+1}の間の範囲を等間隔に分割し、その間の実数を表現する。

このアイデアをもう少しきちんと表すと(1)のように表現できる。 例として、PIの32ビット浮動小数点数での表現をFigure 1に示す。

v=(1)S×2Ebias×(1+21p×T)\begin{equation} v = (-1)^S \times 2^{E-bias} \times (1 + 2^{1-p} \times T) \end{equation}

floating-point-error-1 Figure 1: Structure of IEEE 754 floating-point format, PI in 32-bit floating point number as an example.

浮動小数点数には16ビット、32ビット、64ビット、128ビットなどの一般的なフォーマットがあり、それぞれのパラメータは次の表で示される。

Parameterbinary16binary32binary64binary128
bias15127102316383
sign bit, SS1111
exponent bits, ww581115
significand bits, tt102352112
precision in bits, pp112453113
unit roundoff, uu2112^{-11}2242^{-24}2532^{-53}21132^{-113}

丸め誤差

ある実数をコンピュータ上で扱うには、その数値を浮動小数点数に変換する必要がある。 IEEE 754-2019 [1]では、変換手法として以下5種類の丸め方が定義されている。 バイナリ浮動小数点数では、デフォルトの丸め方法はroundTiesToEvenである。

Rounding AttributeRounding to …
roundTiesToEven与えられた数に最も近い浮動小数点数。ただし、2つの浮動小数点数が同じ距離にある場合は、最下位ビット(LSB)がゼロの浮動小数点数。
roundTiesToAway与えられた数に最も近い浮動小数点数。ただし、2つの浮動小数点数が同じ距離にある場合は、絶対値が大きいほうの浮動小数点数。
roundTowardPositive与えられた数以上の最も近い浮動小数点数。
roundTowardNegative与えられた数以下の最も近い浮動小数点数。
roundTowardZero絶対値が、与えられた数以下のもので、最も近い浮動小数点数。

浮動小数点数に変換する際の丸め誤差

ある実数xRx \in \mathbb{R}を浮動小数点数で表現する場合、誤差の大きさはx|x|に依存して変化する。 ただ、誤差の比率δ\deltaは一般的に(2)のように表現できる。このことを確認してみよう。

fl(x)=x(1+δ),δ<u\begin{equation} fl(x) = x(1 + \delta), \quad |\delta| < u \end{equation}

まず誤差の絶対値は、significant bitの1ビット分よりは小さい。

fl(x)x<2Ebias×12t\begin{equation} |fl(x) - x| < 2^{E-bias} \times \frac{1}{2^t} \end{equation}

さらに、xxが最も近い浮動小数点数に丸められると仮定すると、誤差の大きさはもう半分にまでつめられる。

fl(x)x2Ebias×u\begin{equation} |fl(x) - x| \le 2^{E-bias} \times u \end{equation}

このことから、誤差の比は次のように評価できる。

fl(x)xx<2Ebias×u2Ebias=u\begin{equation} \left| \frac{fl(x) - x}{x} \right| < \frac{2^{E-bias} \times u}{2^{E-bias}} = u \end{equation}

ちなみに、浮動小数点数の指数部が2Ebias2^{E-bias}である場合、元の実数の範囲は[2Ebias2Ebias2p+1, 2Ebias+12Ebias2p)[2^{E-bias}- \frac{2^{E-bias}}{2^{p+1}},~2^{E-bias+1}-\frac{2^{E-bias}}{2^{p}})となる。 なので、誤差比を評価する際に2Ebias2^{E-bias}xxを代表させてしまうのは、あまいようにも思える。 しかし、もしx<2Ebiasx < 2^{E-bias}であれば、最大誤差は2Ebias×12p2^{E-bias} \times \frac{1}{2^{p}}の半分以下になるので、その場合には誤差比が最大になることはない。 そのため、誤差比の評価においては2Ebias2^{E-bias}xxを代表させてしまって問題ない。

内積計算における誤差評価

もしxxyyが誤差なしの浮動小数点数である場合、単一の演算による誤差は次のように表現されることが一般的である。

fl(x op y)=(x op y)(1+δ),δu,op=+, , , /\begin{equation} fl(x~\mathrm{op}~y) = (x~\mathrm{op}~y)(1 + \delta),\quad |\delta| \le u, \quad \mathrm{op} = +,~-,~*,~/ \end{equation}

ここでは、各演算の詳細には立ち入らずに、この仮定を飲み込むことにして、それをもとに内積計算(7)によって生じる誤差について議論しよう。 誤差の大きさは演算の順序に依存するので、左から右へ演算を行うことを仮定して、誤差量を評価する。

si=x1y1++xiyi\begin{equation} s_i = x_1 y_1 + \cdots + x_i y_i \end{equation}

内積計算の項数が小さい場合から順に、具体的な誤差評価の式は次のように表現できる。

s^1=fl(x1y1)=x1y1(1+δ1)\begin{equation} \hat{s}_1 = fl(x_1 y_1) = x_1 y_1 (1 + \delta_1) \end{equation} s^2=fl(s^1+x2y2)=(s^1+x2y2(1+δ2))(1+δ3)=(x1y1(1+δ1)+x2y2(1+δ2))(1+δ3)=x1y1(1+δ1)(1+δ3)+x2y2(1+δ2)(1+δ3)\begin{align} \hat{s}_2 &= fl(\hat{s}_1 + x_2 y_2) = (\hat{s}_1 + x_2 y_2 (1 + \delta_2))(1 + \delta_3) \notag \\ &= (x_1 y_1 (1 + \delta_1) + x_2 y_2 (1 + \delta_2))(1 + \delta_3) \notag \\ &= x_1 y_1 (1 + \delta_1)(1 + \delta_3) + x_2 y_2 (1 + \delta_2)(1 + \delta_3) \end{align} s^3=fl(s^2+x3y3)=(s^2+x3y3(1+δ4))(1+δ5)=(x1y1(1+δ1)(1+δ3)+x2y2(1+δ2)(1+δ3)+x3y3(1+δ4))(1+δ5)=x1y1(1+δ1)(1+δ3)(1+δ5)+x2y2(1+δ2)(1+δ3)(1+δ5)+x3y3(1+δ4)(1+δ5)\begin{align} \hat{s}_3 &= fl(\hat{s}_2 + x_3 y_3) = (\hat{s}_2 + x_3 y_3 (1 + \delta_4))(1 + \delta_5) \notag \\ &= (x_1 y_1 (1 + \delta_1)(1 + \delta_3) + x_2 y_2 (1 + \delta_2)(1 + \delta_3) + x_3 y_3 (1 + \delta_4))(1 + \delta_5) \notag \\ &= x_1 y_1 (1 + \delta_1)(1 + \delta_3)(1 + \delta_5) + x_2 y_2 (1 + \delta_2)(1 + \delta_3)(1 + \delta_5) \notag \\ &\hspace{12pt}+ x_3 y_3 (1 + \delta_4)(1 + \delta_5) \end{align}

これをn項まで拡張すると、次のように表現できる。

s^n=fl(s^n1+xnyn)=(s^n1+xnyn(1+δ2n2))(1+δ2n1)=x1y1(1+δ1)(1+δ3)(1+δ2n1)+x2y2(1+δ2)(1+δ3)(1+δ2n1)+x3y3(1+δ4)(1+δ5)(1+δ2n1)+xnyn(1+δ2n2)(1+δ2n1),\begin{align} \hat{s}_n &= fl(\hat{s}_{n-1} + x_n y_n) = (\hat{s}_{n-1} + x_n y_n(1 + \delta_{2n-2}))(1 + \delta_{2n-1}) \notag \\ &= x_1y_1 (1 + \delta_1)(1 + \delta_3) \cdots (1 + \delta_{2n-1}) \notag \\ &\hspace{11pt}+ x_2y_2 (1 + \delta_2)(1 + \delta_3) \cdots (1 + \delta_{2n-1}) \notag \\ &\hspace{11pt}+ x_3y_3 (1 + \delta_4)(1 + \delta_5) \cdots (1 + \delta_{2n-1}) \notag \\ &\hspace{51pt}\vdots \notag \\ &\hspace{11pt}+ x_ny_n (1 + \delta_{2n-2})(1 + \delta_{2n-1}), \end{align}

任意の i=1,2,i = 1, 2, \cdotsに対してδi<u|\delta_i| < uであることを利用すると、誤差の範囲をより簡単な形で抑えることができる。 [2]によると、複数の(1+δi)(1 + \delta_i)たちの積の範囲は次のように表される。

i=1n(1+δi)=1+θn,whereθnnu1nu\begin{align} \prod_{i=1}^n (1 + \delta_i) = 1 + \theta_n, \quad \mathrm{where} \quad |\theta_n| \le \frac{nu}{1 - nu} \end{align}

このことから、内積計算の誤差は次のように評価できる。

xTyfl(xTy)nu1nui=1nxiyi\begin{align} |\bm{x}^T \bm{y} - fl(\bm{x}^T \bm{y})| \le \frac{nu}{1 - nu} \sum_{i=1}^n |x_i y_i| \end{align}

ベルヌーイの不等式

実は、(12)の関係式はもう少し詰めることができる[3]。 ここでは、i=1n(1+δi)\prod_{i=1}^n (1 + \delta_i)の範囲が(14), (15)のように抑えることができ、結果として(12)も成り立っていることを確認する。 ただし、パラメータの範囲をn=2,3,n = 2, 3, \cdots0<u10 < u \ll 1と仮定する。

i=1n(1+δi)(1u)n>1nu\begin{align} \prod_{i=1}^n (1 + \delta_i) \ge (1 - u)^n > 1 - nu \end{align} i=1n(1+δi)(1+u)n1+nu1+(1n)u\begin{align} \prod_{i=1}^n (1 + \delta_i) \le (1 + u)^n \le 1 + \frac{nu}{1 + (1-n)u} \end{align}

下から抑える式(14)は、ベルヌーイの不等式と呼ばれるもので、数学的帰納法で簡単に確認できる。 まずk=2k=2のとき、次の不等式が成り立つ。

(1u)2=12u+u2>12u\begin{align} (1-u)^2 = 1 - 2u + u^2 > 1-2u \end{align}

次に、(1u)k1ku(1 - u)^k \ge 1 - kuが成り立つと仮定して、全体に(1u)(1 - u)を掛けると、次の不等式が得られる。 よって、(14)が数学的帰納法により成立する。

(1u)k+1(1ku)(1u)=1(k+1)u+ku2>1(k+1)u\begin{align} (1 - u)^{k+1} \ge (1 - ku)(1 - u) = 1 - (k+1)u + ku^2 > 1 - (k+1)u \end{align}

次に、上から抑える式(15)を確認する。 (1u1+u)n(1 - \frac{u}{1+u})^nを(14)に適用すると、次の不等式が得られる。

(1u1+u)n>1nu1+u\begin{align} \left( 1 - \frac{u}{1+u} \right)^n > 1 - n \frac{u}{1+u} \end{align} 1(1+u)n>1+unu1+u\begin{align} \frac{1}{(1+u)^n} > \frac{1+u-nu}{1+u} \end{align}

いま、1+unu>01 + u -nu > 0とすると、(15)が得られる。

(1+u)n<1+u1+unu=1+nu1+(1n)u\begin{align} (1 + u)^n < \frac{1+u}{1+u-nu} = 1 + \frac{nu}{1 + (1-n)u} \end{align}

Reference

  1. “IEEE Standard for Floating-Point Arithmetic” in IEEE Std 754-2019 (Revision of IEEE 754-2008), pp.1-84, 22 July 2019, doi: 10.1109/IEEESTD.2019.8766229.
  2. Nicholas J. Higham, “Accuracy and Stability of Numerical Algorithms, Second Edition”, Society for industrial and applied mathematics, 2002.
  3. Dragoslav S. Mitrinović, “Analytic Inequalities”, Springer Berlin, Heidelberg, 1970.

関連記事

いろいろな形状の表面に点を一様分布させる

輻射熱伝達をレイトレーシングによって評価する場合、物体表面から一様に光線を発生させる必要があります。今回は、長方形・三角形・円板・球面・円柱・円錐・放物面などの基本的な表面形状について、0–1の範囲のランダム値からどうやって一様分布を発生させるかを解説します。

APDLコマンドを用いたAnsys Workbench解析結果のエクスポート

Ansys Workbenchで得られた解析結果をエクスポートしたい場合、APDLコマンドを使用することで、より柔軟にフォーマットを指定して出力することが可能です。本記事では、熱解析のモデルデータおよび解析結果をCSV形式でエクスポートする方法を紹介します。

ルンゲクッタ法(RK4)の精度確認

常微分方程式の時間発展を計算する際に、手軽に用いられる手法にルンゲクッタ法(RK4)があります。この記事では、ルンゲクッタ法が4次精度を達成していることを確認します。