メインコンテンツまでスキップ

誤差

ここでは、誤差について扱います。誤差は、期末テストなどで聞かれやすい分野であり、用語を忘れやすい分野でもあるので、気をつけてください。

浮動小数点数

コンピューターでは、浮動小数点方式が使われます。浮動小数点方式では、仮数部と指数部によって数値を表現します。

12345=1.2345仮数部×104指数部12345 = \underbrace{1.2345}_{\text{仮数部}}\times 10^{\overbrace{4}^{\text{指数部}}}

物理的制約があるので、仮数部と指数部は有限桁でしか扱えません。

丸め誤差

丸め誤差とは

世の中には、有限桁の小数では表せない数字は多くあります。

まずは、10 進数で考えましょう。 例えば、1/31/3 は有限桁の小数では表せません。0.30.30.330.330.3330.3331/31/3 の近似でしかありません。 たとえ、次のようにどんなに桁を大きくしても有限である限り近似であることには変わりがありません。

0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

2 進数においても同じことが起こります。 10 進数の 0.10.1 を 2 進数で表すことを考えます。

0.1(10)=0.0625(10)+0.03125(10)+0.00390625(10)+0.00195332(10)+=116(10)+132(10)+1256(10)+1512(10)+=0.0001(2)+0.00001(2)+0.0000001(2)+0.00000001(2)+=0.000110011(2)\begin{aligned} 0.1_{(10)} &= 0.0625_{(10)} + 0.03125_{(10)} + 0.00390625_{(10)} + 0.00195332_{(10)} + \cdots \\ &= \frac{1}{16}_{(10)} + \frac{1}{32}_{(10)} + \frac{1}{256}_{(10)} + \frac{1}{512}_{(10)} + \cdots \\ &= 0.0001_{(2)} + 0.00001_{(2)} + 0.0000001_{(2)} + 0.00000001_{(2)} + \cdots \\ &= 0.000110011\cdots_{(2)} \end{aligned}

このように 0.1(10)0.1_{(10)} は 2 進数では有限桁で表せません。

コンピューターは 2 進数で処理をするので一度 10 進数を 2 進数に変換しますが、そのときに無限桁を扱うことはできないので、有効桁以降を切り捨てることになります。これによって、誤差が出るのが丸め誤差です。

丸め誤差の例

さきほど述べたように 0.1(10)0.1_{(10)} を二進数で表すと丸め誤差が発生します。そのため、例えば 0.1×30.1\times 3 を計算すると丸め誤差の影響が現れます。

Open In Colab

桁落ち

桁落ちとは

有効数字 7 桁で 1001999\sqrt{1001}-\sqrt{999} を計算することを考えます。

1001=31.63858431.63858\sqrt{1001} = 31.638584\dots \simeq 31.63858
909=31.60696131.60696\sqrt{909} = 31.606961\dots \simeq 31.60696

よって、

10019990.03162\sqrt{1001}-\sqrt{999} \simeq 0.03162

このようにすると、有効数字が 4 桁に減ってしまいます。

このように値がほぼ同じ数値同士で減算をしたときに有効桁数が減少することによって生まれる誤差が桁落ちです。

回避策

実は今回の場合は、回避策があります。

1001999=(1001999)(1001+999)1001+999=10019991001+999=21001+999231.63858+31.60696=263.245540.03162278\begin{aligned} \sqrt{1001}-\sqrt{999} &= \frac{(\sqrt{1001}-\sqrt{999})(\sqrt{1001}+\sqrt{999})}{\sqrt{1001}+\sqrt{999}} \\ &= \frac{1001-999}{\sqrt{1001}+\sqrt{999}} \\ &= \frac{2}{\sqrt{1001}+\sqrt{999}} \\ &\simeq \frac{2}{31.63858+31.60696} \\ &= \frac{2}{63.24554} \\ &\simeq 0.03162278 \end{aligned}

今回の場合ならば、これで桁落ちを回避できます。

桁落ちの例

少し桁を大きくして、実際に確かめてみましょう。

上が桁落ちが起こってしまった例で、下が桁落ちを回避した例です。確かに、上はずれてしまいましたね。

Open In Colab
Open In Colab

情報落ち

情報落ちとは

次の場合、有効数字が 5 桁なら

1.0000×104+1.0000=1.0001×1041.0001×104\begin{aligned} 1.0000\times 10^4 + 1.0000 &= 1.0001 \times 10^4 \\ &\simeq 1.0001 \times 10^4 \end{aligned}

となって正しく計算できますが、有効数字が 4 桁だと、

1.000×104+1.000=1.0001×1041.000×104\begin{aligned} 1.000\times 10^4 + 1.000 &= 1.0001 \times 10^4 \\ &\simeq 1.000 \times 10^4 \end{aligned}

となって正しく計算できません。

次のように、何度も足す場合には深刻になってきます。

1.000×104+4.000+4.000+4.000=1.0004×104+4.000+4.0001.000×104+4.000+4.0001.000×104\begin{aligned} 1.000\times 10^4 + 4.000 + 4.000 + 4.000 &= 1.0004 \times 10^4 + 4.000 + 4.000 \\ &\simeq 1.000 \times 10^4 + 4.000 + 4.000 \\ &\simeq \cdots \\ &\simeq 1.000 \times 10^4 \end{aligned}

このように、絶対値の大きい数と絶対値の小さい数を加減算したときに、絶対値の小さな数字が無視されてしまうことを情報落ちといいます。

回避策

これには、回避策があります。

小さい数を先に足して、その後に大きい数を足せば回避できます。

4.000+4.000+4.000+1.000×104=8.000+4.000+1.000×104=12.000+1.000×104=1.0012×1041.001×104\begin{aligned} 4.000 + 4.000 + 4.000 + 1.000\times 10^4 &= 8.000 + 4.000 + 1.000 \times 10^4 \\ &= 12.000 + 1.000 \times 10^4 \\ &= 1.0012 \times 10^4 \\ &\simeq 1.001 \times 10^4 \\ \end{aligned}

これで、有効数字 4 桁で正しい計算ができました。

情報落ちの例

10000000000 に 0.0000001 を 10000000 回足すと、10000000001 になります。しかし、上の計算では正しく計算できていません。一方、下の計算では正しく計算できます。

Open In Colab
Open In Colab