あざらしとペンギンの問題

主に漫画、数値計算、幾何計算、TCS、一鰭旅、水族館、鰭脚類のことを書きます。

ななついろ☆ドロップアウト

この時期にドロップアウトとは穏やかじゃないですが、筆者一押しの4コマ漫画である『スロウスタート』のアニメは遅れもなく始まり、私だけ取り残されました。私事しか書かないブログですが、今年もよろしくお願いします。(本当は1月中に公開する予定でしたが、諸事情により遅れました。)

さて、今回のタイトルの由来である『ななついろ☆ドロップス』とは、2006年に18禁 PC ゲームとして発売され、2007年にアニメ化された作品です。ディオメディアの初元請作品*1であり、筆者においては初めてくらいに観た UHF アニメでした。そんなわけで記念すべき作品のひとつにとして使いました。

今回取り上げるのは、計算機上で小数を扱う際に重要な問題となってくる『桁落ち』という現象です。

結論から言えば、『桁落ち』とは「近接した値同士で引き算をすると結果の不確かさが異常に大きくなる」ということです。かなり微妙な言い回しですが、ともかく「引き算には気をつけろ」といった意味だと今は思っておいて結構です。

小数と誤差

計算機上では普通は2進小数が使われるのですが、『桁落ち』および『情報落ち』は特に基数に依存するものではないので、我々にとって馴染み深い10進小数*2で説明します。

有効数字と誤差

現代において我々は整数でない数を小数で表し、特に無限小数となる場合は有限桁の小数で打ち切ることを日常的に行っています。例えば、

\displaystyle \sqrt{2} = 1.41421356\dots
\displaystyle \pi = 3.14159265\dots

のように。あるいは、打ち切る桁より下の位に丸め(四捨五入など)、切り上げ、切り下げのいずれかを行って

\displaystyle \sqrt{2} = 1.4142 \times 10^0
\displaystyle \pi = 3.1416 \times 10^0

のように表したりもします。これらの例は6桁目を四捨五入したものです。前にある小数は『仮数部』(mantissa)、10 の肩に乗っている数は『指数部』(exponent) と言います。仮数部は必ず 1 以上 10 未満の範囲に入っていなければなりません。この形式は自然科学や工学において不確さを含む値を表記するときと同じです。ただし、この等号は真の等号ではないことに注意が必要です。

上の例では5桁の数字に意味があるので、『有効数字』5桁の値と言います。

有効数字の桁数は先頭の0でない桁から数えます。例えば、

\displaystyle \frac{23}{4567} = 0.0050361287\dots = 5.0361 \times 10^{-3}

のように、元の小数の6桁目を丸めたのでなく、最初に0でない数字が出る桁から数えて6桁目を丸めた値を、有効数字5桁の値として採用します。なお、このような形式の小数を『浮動小数点数』と言います。計算機における小数の実装のほとんど(C言語の double など)は2進浮動小数点数です。

数に丸めや打ち切りなどを行うと、それに伴う誤差が発生します。これを『丸め誤差』や『打ち切り誤差』と言います。例えば、

\displaystyle \pi = 3.1416 \times 10^0

は真の値から 0.0000073464\dots だけ大きくなっています。一方、これを真の値から 0.00023384\dots \% だけ大きいと表現することもあります。前者を『絶対誤差』、後者を『相対誤差』と言います。それについては次に回すとして、実数を有限桁で表す以上は、誤差は常について回ります。誤差には無論、測定誤差などの元々の数値に含まれる誤差も含まれます。

なお、打ち切りの場合を除いて、有効数字はその桁数の真の値の表示とは一致しないことがあります。上の例では5桁目の数字が異なっています。

このように「有効数字xx桁」という表現の意味するところは曖昧です。あくまで、精度を考える上で『不確かさ』を含む位以下を除いた数字を数えているだけであり、その桁数がどういう意味を持つかは、誤差の意味や計算上の丸めモードなどによって異なります。しかし、この記事においては以後も「有効数字xx桁」という表現を使うことにします。桁落ちを説明するにはそれで十分だからです。

絶対誤差と相対誤差

さて、少し前の文で『絶対誤差』と『相対誤差』という言葉が出てきました。例えば、

\displaystyle \sqrt{2} = 1.4142 \times 10^0
\displaystyle \pi = 3.1416 \times 10^0
\displaystyle \frac{23}{4567} = 5.0361 \times 10^{-3}

のそれぞれの右辺の値にはすべて丸め誤差が含まれています。このような誤差は大きく2種類に分けられるということです。

その2種類とはすなわち『絶対誤差』と『相対誤差』であり、次のように定義されます。ここで、x^* は真の値、 \tilde{x} は誤差を含む値とします。

絶対誤差:
\displaystyle \epsilon_a = \left| \tilde{x} - x^* \right|

相対誤差:
\displaystyle \epsilon_r = \frac{\epsilon_a}{x^*} = \frac{\left| \tilde{x} - x^* \right|}{x^*}

相対誤差に関する見やすい例では、真の値 100 に対する 100.003、それと真の値 100000 に対する 100003 を誤差の意味で同じと見なします。双方とも言葉では「真の値より 0.003% だけ大きい」と言うことができます。

これらの二つの誤差のうち、浮動小数点数では絶対誤差ではなく相対誤差の方が重要です。というのも、数の大きさが指数部に依存するためです。前文の例では、有効数字5桁として

\displaystyle 100.003 = (1.0000 + 0.00003) \times 10^{2}
\displaystyle 100003 = (1.0000 + 0.00003) \times 10^{4}

であり、両者は仮数部の誤差の意味で全く同じであることがわかります。ここで、1.0000 と 1 が異なる意味を持ち、両者を区別しなければならないことは、学校の理科の授業などで注意されたと思います。あくまで有効数字の意味の取り方ひとつとして、真の値 x^* と誤差を含む値 \tilde{x} との間で

\tilde{x} = 1.00000.99995 \le \tilde{x} < 1.00005
\tilde{x} = 10.5 \le \tilde{x} < 1.5

を意味すると仮定します。このとき、誤差を含む値の『不確かさ』を有効数字の桁数で表しているため、必然的に区別が必要なのです。ここでは有効数字5桁としたので、6桁目を四捨五入すると、

\displaystyle 100.003 = 1.0000 \times 10^{2}
\displaystyle 100003 = 1.0000 \times 10^{4}

となります。

この通り、浮動小数点数では誤差を相対誤差で見ることにより、仮数部に関するものに限定することができます。逆に、もし計算機が5桁までの値しか扱えないならば、仮数部の 0.00005 の不確かさを除去することができません。*3

このような計算機の有限性の制限のため生じる誤差の範囲を『マシンイプシロン』と呼んだりします。ただし、この言葉は絶対誤差の意味でも使われるため、曖昧な表現であることに注意が必要です。

ところで、今まで『誤差』と『不確かさ』という二つの言葉を使ってきましたが、この記事では両者を明確に区別して使うことにします。

『誤差』とは本節の最初に定義された『絶対誤差』または『相対誤差』のみを指すものとします。

対して、有効数字から外れるために誤差として扱われる部分の範囲を『不確かさ』と呼ぶことにします。有効数字という言葉が曖昧性を含むように、不確かさという言葉も曖昧性を含むことは注意しておきます。先にも断った通り、この曖昧性は本記事において重要ではありません。

計算による不確かさの拡大

さて、敢えて『不確かさ』という曖昧な言葉を使うことのいくつかの理由のひとつは、丸め誤差や打ち切り誤差を含む値同士で計算を行ったとき、一般に誤差の範囲が拡大するためです。例えば、有効数字5桁、6桁目を四捨五入するとして、小数を用いた計算では

\displaystyle \frac{1}{3} + \frac{1}{3} = 3.3333 \times 10^{-1} + 3.3333 \times 10^{-1} = 6.6666 \times 10^{-1}

となるところが、真の値を四捨五入すると

\displaystyle \frac{1}{3} + \frac{1}{3} = \frac{2}{3} = 6.6667 \times 10^{-1}

となることなどがあります。第一の計算値については

\displaystyle 6.6666\dots \times 10^{-1} < \left(\frac{2}{3} - 0.00005 \right) \times 10^{-1}

であるため、6桁目の四捨五入によって許容される誤差の範囲に収まっていないことが判ります。このように、有効数字の桁数はあくまで精度の目安であって、厳密な誤差の範囲を表すものではないことに注意が必要です。

ここまで、誤差を含む値を表すのに考えなく等号を使ってきましたが、当然のことながらその等号は正しくありません。また、計算による不確かさの拡大があるため、計算順序も重要な問題である。本題の『桁落ち』とは、最初に書いた通り、計算による不確かさの拡大を意味します。

そこで、計算の推移を \to、真の値から小数への変換を \Rightarrow 単に値が近いことを \approx、値が右に示される区間に入っていることを \in で表すことにします。上の例では、

\displaystyle \frac{1}{3} + \frac{1}{3} \Rightarrow 3.3333 \times 10^{-1} + 3.3333 \times 10^{-1} \to 6.6666 \times 10^{-1}
\displaystyle \frac{1}{3} + \frac{1}{3} \to \frac{2}{3} \Rightarrow 6.6667 \times 10^{-1}
\displaystyle \frac{2}{3} \approx 6.6667 \times 10^{-1}
\displaystyle \frac{2}{3} \in (6.6667 \pm 0.00005) \times 10^{-1}

のように表されます。

相対誤差の上界

ここでひとつ相対誤差について注意すべきことがあります。本来、相対誤差の定義では真の値から見た誤差を測るべきところが、これまでの例では誤差を含む値から見た真の値の存在する範囲を示しているのです。当然ですが両者は同じではありません。実を言えば我々は数値計算によって相対誤差それ自体を厳密に知ることはできません。というのも、我々が計算機上で扱う値は誤差を含む値の方だからです。

とは言っても、相対誤差の取りうる値の上界を見積もることは可能です。まず、誤差を含む値 \tilde{x}仮数部と指数部に分けて

\displaystyle \tilde{x} = m \times 10^e

とします。ここで 1 \le |m| < 10 かつ e は整数です。

このとき、相対誤差の上界は、\epsilon > 0 として

\displaystyle x^* \in (m \pm \epsilon) \times 10^e

のとき

\displaystyle \epsilon_r \le \frac{\epsilon \times 10^e}{(|m| - \epsilon) \times 10^e} = \frac{\epsilon}{|m| - \epsilon} < \frac{\epsilon}{1 - \epsilon}

となります。

ここで  |m| = 1 と置いて上界を取ったことはいささか乱暴に思われるでしょう。もし |m| = 9 ならば、誤差を9倍以上緩く見積もっていることになります。

この上界の緩さを狭めるには、2進小数を使うことが最良の方法となります。なぜなら、2進小数では |m| = 1 に限定されるためです。その場合、誤差の見積もりは高々2倍以内に収まります。計算機では2進小数が使われるのが普通ですが、機械的な実装だけでなく誤差の見積もりの意味でも、2進小数を使う方が有利なのです。

そのような事情はあるものの、この記事ではあくまでわかりやすさのために、我々にとって馴染み深い10進小数を使います。

10進で有効数字  k \ge 6*4(k + 1) 桁目を四捨五入するとした場合、\epsilon = 5 \times 10^{-(k + 1)} なので、相対誤差の上界を乱暴に計算すると

\displaystyle \epsilon_r < \frac{\epsilon}{1 - \epsilon} < 1.000006 \times 5 \times 10^{-k} =  5.00003 \times 10^{-(k + 1)}

となります。

桁落ち

さて、ここまでは準備で、本題はここからです。

最初に言ったように、『桁落ち』とは「相対的に近接した値同士で引き算をすると相対的な不確かさが異常に大きくなる」ということです。問題点をより明らかするために、『近接』と『不確かさ』の前に『相対的な』を付けたことに注意してください。

本節においても、小数は10進有効数字5桁で6桁目を四捨五入するものとします。このように有限個の数字で計算を行うことは、この問題に関して本質的です。

桁落ちの例

まず、次のような大きさの極端に異なる数の足し算を行ってみます。

\displaystyle \sqrt{2} + \frac{23}{4567} \Rightarrow (1.4142 + 0.0050361) \times 10^0 \to 1.41923 \times 10^0 \to 1.4192 \times 10^0

この計算により、誤差そのものは最初の誤差の上限 0.00005 より増えている可能性がありますが、この時点では相対的な不確かさの拡大は小さなものに収まっています。実際、

\displaystyle \sqrt{2} + \frac{23}{4567} = 1.4192496911228\dots \in (1.4192 \pm 0.00005) \times 10^0

なので、厳密な相対誤差の意味でも想定内に収まっていることが判ります。

問題は、先程求めた値 1.4192 \times 10^0 から \sqrt{2} = 1.4142 \times 10^0 を引くことによって発生します。注意すべきはこの時点で持っている値が 1.4192 \times 10^01.4142 \times 10^0 以外の何物でもないことです。あくまで数値のみで計算を行うため、記号としての \sqrt{2} などは忘却の彼方にあるというわけです。それでは実際に引いてみましょう。

\displaystyle 1.4192 \times 10^0 - 1.4142 \times 10^0 \to 0.0050 \times 10^0 = 5.0 \times 10^{-3}

はい。有効数字2桁になりました。5.0 \times 10^{-3}5.0000 \times 10^{-3} の違いを思い出してください。真の値を5桁に丸めたものは 5.0361 \times 10^{-3} なので、不確かさの拡大は厳密な相対誤差の拡大とも合致します。

改めて全体の計算を書くと、

\displaystyle \left( \sqrt{2} + \frac{23}{4567} \right) - \sqrt{2} \Rightarrow \left( (1.4142 + 0.0050361) - 1.4142 \right) \times 10^0
\displaystyle \to (1.4192 - 1.4142) \times 10^0 \to 5.0 \times 10^{-3}

となります。

以上のことをもって『桁落ち』が生じたと言います。

桁落ちはとにかく悪い

桁落ちの何が問題かというと、計算値の相対的な不確かさが他の四則演算に比べて異常に増えることです。

馴染み深い例は微分を数値的に計算するときに現れます。まず微分係数の定義式が

\displaystyle f'(x) = \lim_{h \to 0} \frac{f(x + h) - f(x)}{h}

であることは言うまでもありませんが、この式より(悪い)自明な計算方法として $h$ を適当に小さな値に取って式を評価するということが考えられるでしょう。ここでも計算は全体を通して有効数字5桁で行われるとします。

以下、$f(x) = \sqrt{x}$ として $x = 2$ ちょうどでの微分係数数値計算することを考えます。真の値は

\displaystyle f'(2) = \frac{1}{2 \sqrt {2}} = 0.35355339059 \in 3.5355339 \times 10^{-1}

です。

$h$ は適当に小さな値として $h = 0.001$ ちょうどを取るとしよう。このときの計算は


先程より少しマシな結果が得られていますね。結果が2桁まで合っていることが見て取れます。


\displaystyle \frac{\sqrt{2 + 0.001} - \sqrt{2}}{0.001} \Rightarrow \frac{\sqrt{2.0000 + 0.0010} - \sqrt{2.0000}}{0.0010000}
\displaystyle \to (\sqrt{2.0010} - \sqrt{2.0000}) \times 1000.0 \to (1.4146 - 1.4142) \times 1000.0
\displaystyle \to 0.40000 = 4.0000 \times 10^{-1}

となり、大きく異なった値が出ることがわかります。

このように、桁落ちは不確かさが異常に大きくなることにより、どのような意味でも精度の悪い計算結果を生み出してしまうのです。

なお、よく知られた方法として、中心差分を用いた公式

\displaystyle f'(x) = \lim_{h \to 0} \frac{f(x + h) - f(x - h)}{2 h}

を用いて計算すると良い計算値が出せるというものがあります。これによれば、同じ有効数字5桁のもとで $f'(2)$ は次のように計算されます:

\displaystyle \frac{\sqrt{2 + 0.001} - \sqrt{2 - 0.001}}{2 \times 0.001} \Rightarrow \frac{\sqrt{2.0000 + 0.0010000} - \sqrt{2.0000 - 0.0010000}}{2 \times 0.0010000}
\displaystyle \to (\sqrt{2.0010} - \sqrt{1.9990}) \times 500.00 \to (1.4146 - 1.4139) \times 500.00
\displaystyle \to 0.3500 = 3.5000 \times 10^{-1}

それにはちゃんとした理由があります。次の図より直感的にはわかってもらえることを期待します。

f:id:azapen6:20151222103901p:plain

しかし、この設定でこれ以上良い結果を得ることはおそらく不可能でしょう。なぜなら、有効数字5桁では $2.000 + 0.0010000 \Rightarrow 2.0010$ となるように、$0.0010000$ のうち2桁より下の情報が失われてしまうためです。それを次節で説明します。

桁落ちと情報落ち

『桁落ち』と関係する言葉として『情報落ち』というものがあります。これは、桁数が有限であるために元々の数が持っていた情報が計算によって失われることを指して言う言葉です。例えば、先に出した例:

```math
\sqrt{2} + \frac{23}{4567} \Rightarrow (1.4142 + 0.0050361) \times 10^0 \to 1.41923 \times 10^0 \to 1.4192 \times 10^0
```

では後ろの桁の情報 361 が失われていることから『情報落ち』が発生しています。これは一般には『積み残し』と呼ばれ、桁違い*5に大きさの異なる数を足し引きしたときに発生するものです。

しかし、この段階では有効桁数はほとんど失われていないことに注意が必要です。つまり、『情報落ち』こそ発生していますが、『桁落ち』が発生したとまでは言えません。

『桁落ち』が発生するのは近接した値の引き算を行ったときする。上の結果から $\sqrt{2} \in 1.4142 \times 10^0$ を引いて

```math
1.4192 \times 10^0 - 1.4142 \times 10^0 \to 0.0050 \times 10^0 = 5.0 \times 10^{-3}
```

としたとき、初めて『桁落ち』が発生します。

『桁落ち』の原因は上位桁が等しい数の有効数字がキャンセルされてしまうことです。すなわち、データとして見れば『情報落ち』の範疇に含まれます。しかし、『桁落ち』は単なる情報落ちに留まらず、有効数字が著しく失われることを特に指して言う言葉です。有効数字がほとんど失われない『情報落ち』も避けるに越したことに違いはありませんが、『桁落ち』はそれよりずっと重要な問題であり、小さくない犠牲を払ってでも避けられるべきなのです。

桁落ちの回避

桁落ちを回避する方法は、とにもかくにも、その原因となる「近接した値同士の引き算」を行わないようにすることです。それには、計算する対象についての事前知識があると、有利に進めることができる場合があります。

完全に同じ値の引き算を記号的に除去する

前節のひとつ前例では、完全に同じとわかっている値を記号的に引いてしまってから、小数としての計算を行うことによって、桁落ちを回避できます。

\displaystyle \frac{1}{\left( \sqrt{2} + \frac{23}{4567} \right) - \sqrt{2}} \to \frac{1}{\left( \sqrt{2} - \sqrt{2} \right) + \frac{23}{4567}} \to \frac{4567}{23}
\Rightarrow \frac{4.5670 \times 10^3}{2.3000 \times 10^1} \to 1.9857 \times 10^2

馬鹿馬鹿しい例ですが、記号のまま処理できる部分を先に記号のまま処理しておくことは、桁落ちを回避する上で重要なことです。あるいは、数学的、物理的な知見からの不変性、対称性が利用できるかもしれません。

分母、分子の有理化

平方根の引き算を伴う計算では、分母または分子の有理化を行うことによって、桁落ちが回避できる場合があります。

重要な例として二次方程式の解の公式が挙げられます。中学校で習うように、二次方程式  ax^2 + bx + c = 0\;(a \neq 0) の解は

\displaystyle x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}

という公式によって求められます。ここで、b > 0 とした場合、解の一方の計算式(以下にある $x_1, x_2, x_3$ は計算式であって、それを評価した値ではないとします。これを厳密に区別して、定義式に $:=$ を使うことにします。)

\displaystyle x_1 := \frac{-b + \sqrt{b^2 - 4ac}}{2a}

の分子

\displaystyle -b + \sqrt{b^2 - 4ac}

は近接した値の引き算(負の数と正の数の足し算なので、符号が逆の引き算に同じ)となる場合があります。そこで、分子の有理化を行うと、

\displaystyle x_2 := \frac{-b + \sqrt{b^2 - 4ac}}{2a} = -\frac{2c}{b + \sqrt{b^2 - 4ac}}

となって、問題となる引き算を回避できます。実際の計算例を示します。

二次方程式 x^2 + 1.0001 x - 1 = 0 について、解のひとつを解のひとつを32ビット浮動小数点数(10進有効数字7桁程度)の範囲内で x_1x_2 のそれぞれの公式に当てはめて計算してみます。

コードと計算結果:https://ideone.com/yYpLa7

結果をここに書くと、

x_1 = 4.998446 \times 10^{-4}
x_2 = 4.998751 \times 10^{-4}

となりました。真の値は x^* = 4.99875086\dots なので、x_1 はかなり精度が悪く、一方で x_2 は十分な精度を持った値であることが判ります。最後の桁が異なるのは32ビット浮動小数点数の精度では仕方のないことです。

級数展開を使う

前の二次方程式の解の公式の問題を、級数展開を使って解決することも考えられます。問題の引き算

\displaystyle -b + \sqrt{b^2 - 4ac}

で桁落ちが発生するときというのは、4ac \ll b^2 となるときです。少し変形すると、

\displaystyle -b + \sqrt{b^2 - 4ac} = -b + b \sqrt{1 - \frac{4ac}{b^2}} = b \left( \sqrt{1 - \frac{4ac}{b^2}} - 1 \right)

において 4ac / b^2 \ll 1 となるときとも言えます。このとき、一般化二項定理により得られる級数展開

\displaystyle \sqrt{1 - \frac{4ac}{b^2}} = 1 - \frac{2ac}{b^2} - \frac{2 a^2 c^2}{b^4} \dots

は良い近似になっていると考えられます。式の中に引き算が出てきますが、近接した値でないことが保証されているので、桁落ちが問題になるケースではありません。

というわけで、級数を上の3項で打ち切って代入すると、

\displaystyle -b + \sqrt{b^2 - 4ac} = -\frac{2ac}{b} - \frac{2 a^2 c^2}{b^3}

から元の解の公式は

\displaystyle x_3 := -\frac{c}{b} \left( 1 + \frac{ac}{b^2} \right)

となります。ここでも引き算がありますが、やはり仮定より桁落ちが問題となるケースではありません。

計算結果は先のコードの実行結果にある通り

\displaystyle x_3 = 4.998751 \times 10^{-4}

となり、x_2 と同程度に良い値が得られていることがわかります。

加速法を使う

微分方程式の差分解法のような、微分係数の差分近似を含む計算を行うとき、桁落ちはほぼ宿命的に問題となります。この前の記事で微分係数を加速法によって高精度で求める方法を説明しています。

アクセルほど微分精度は加速していくよ! - あざらしとペンギンの問題

引き算には気をつけろ

桁落ちを回避する方法はここに書いた以外にも様々ありますが、どんな場合でも上手くいくような万能の処方箋はありません。とにもかくにも引き算に気をつけるという意識を持つことが第一です。可能ならば引き算を行わないようにすること、回避できない場合は可能な限り回数を減らす、また、ソートを行って順序を変えるなど、工夫して計算を行うことが求められます。

有限性の壁

計算機において有効数字、桁落ち、情報落ちといった概念が出てくる理由は、物質的な制約のために扱えるデータ量が限られることにあります。特には浮動小数点演算装置(FPU)のレジスタが(符号、指数を含めて)少ない桁数の分しかないということです。レジスタを大きくすれば桁数を増やすことはできますが、その分だけ数のデータを保持し、また、処理するためにより大きな、あるいは集積度の高い回路が必要となります。回路の素子は原子で構成されていて、宇宙には有限個の原子しかないので、無限の桁数を扱うことは当然ながら不可能です。それは、数のデータをチップの外、例えばハードディスクやクラウドストレージに入れたとしても同じです。

さらに言えば、データの読み出しはつまるところ測定なので、物理学的な不確かさが本質的に有効数字を限定しているとも考えられます。この不確かさは測定誤差ばかりでなく、量子力学的、統計力学的な不確かさ、つまり、この世界においてどうやっても克服できない不確かさが含まれます。桁数というものが名目上存在しないアナログ計算機でさえ、有効数字の束縛から逃れ得るものではないのです。

まとめ

桁落ちとは、浮動小数点数演算において近接した値の引き算を行うことによって有効数字が失われ、計算値の不確かさが異常に大きくなることでした。桁落ちは数値計算における重要な問題であり、可能な限り回避しなければならないものです。本記事ではいくつかの方法を示しました。前の記事に書いた加速法も桁落ちを回避する手段となり得ます。その他様々な方法がありますが、万能の処方箋はなく、問題を見て工夫すべき場合も少なくありません。本記事の教訓を一言で言えば、

引き算には気をつけろ

これは数値計算を行う上で常に意識しなければならないことです。

桁落ち、情報落ちは有限の世界で計算を行う以上は避けられない問題です。一見すると数値計算における細かく面倒な問題のようで、実は計算の本質に関わる問題であるというのが私の思うところです。

*1:当時の社名はスタジオ・バルセロナ

*2:他の記数法を用いる文化圏では、10進小数が馴染み深いとは言えないかもしれません。

*3:多倍長演算によって任意の桁数を扱うことが可能ですが、計算の速度は極端に落ちます。

*4:IEEE 754 の定める 32 ビット浮動小数点数は10進で有効数字7桁程度

*5:ここでは読んで字のままの意味