次回からは後半戦の「数値計算」シリーズに入るが、その前に今回はテキスト第7.1章に沿って数学の準備をば。 内容は主に「離散数学」と呼ばれるもので、この辺は IT パスポート試験の出題範囲にも含まれている。
数の表現と誤差
10進法と2進法・16進法
これらは数を表現する方法の違い。 我々はふつう10進法でモノを考えているが、我々の日常生活の中にも10進法でないやり方で数を表現している場合がある (例えば時刻の60進法)。 コンピュータに関係する場面では2進法 (や16進法) がよく出てくる。
10進法では、\(0\) から \(9\) の10個の「記号」を使って数を表現する。 例えば \(54321\) という自然数について、それぞれの位のもつ意味を考えると \[ 54321=5\times10^4+4\times10^3+3\times10^2+2\times10^1+1\times10^0 \tag{7.1} \] となる。 ここで使われている「\(10\)」を「底」あるいは「基数」という。 \(10\) を底とし、底とそのべき乗を基準にして数を表わす方法が10進法。
2進法では、\(0\) と \(1\) の2個の「記号」だけを使って数を表現する。 例えば \(54321\) という自然数について \begin{equation} \begin{split} 54321& =1\times2^{15}+1\times2^{14}+0\times2^{13}+1\times2^{12} \\& +0\times2^{11}+1\times2^{10}+0\times2^{9}+0\times2^{8} \\& +0\times2^{7}+0\times2^{6}+1\times2^{5}+1\times2^{4} \\& +0\times2^{3}+0\times2^{2}+0\times2^{1}+1\times2^{0} \end{split} \tag{7.2} \end{equation} であるから、これを2進法で表現すれば \[ 1101010000110001 \] のように、\(0\) と \(1\) が16桁だけ並んだ数として表現される。
10進法で表現された数を2進法の表現に直すこともできる。 手計算でも可能であるし、それ用のツールもいくつも存在する。
ただし2進法を使っているとやたらと桁の数が多くなってしまい、人間には読み づらくなってしまうので、16進法が併用されることが多い。
- 16進法では \(0\) から \(15\) までの16個の記号が必要だが、1桁で表わせない \(10\) から \(15\) は A から F に置き換えて書き表わす。
- 2進法で出てくる記号を4つずつの組に分け、それらを1つの記号で表示し直したものが16進法。
計算機の中での数の表現
これまで学習してきた算数や数学において、「数」といえば数直線のように「無限」とか「連続」というイメージであろう。 しかし、計算機の中ではそれとは異なる取り扱いを受ける。 そのため、特に「計算の精度」を気にする場合にはこの点にも注意すべき。
計算機の中で、情報はすべて2進法に基づいて処理される。
- 2進法の数字1桁を1「ビット(bit)」という。 これが情報の最小単位。
- 8個のビットをまとめたものを「バイト (byte)」という。
計算機の中での整数 (integer) の扱いについて注意すべきことは、整数にも上限と下限があること。 Fortran 90 をはじめとするプログラミング言語で「整数」型変数を宣言すると、ふつうはその変数に4バイト (=32ビット) の容量が与えられる。 ということは、取り扱い可能な整数の個数は \(2^{32}=4294967296\) 個に限られ、その範囲は \(-2^{31}=-2147483648\) から \(2^{31}-1=2147483647\) まで。
計算機の中での実数 (real) は「浮動小数点数 (floating-point number)」という形式で表現されており、一般的には \[ {s}\times{f}\times{\beta^m} \tag{7.3} \] と書かれる。 このうち
- \(\beta\) を「基数 (base)」、\(m\) を「指数 (exponent)」という。 最近の多くの計算機では \(\beta=2\) にとった2進表現が使用されている。
- 符号部 \(s\) は \(+1\) か \(-1\) かのどちらか。
- \(f\) は「仮数部 (mantissa)」で、次の形に表わされる。 \begin{equation} f=\frac{c_1}{\beta^1}+\frac{c_2}{\beta^2}+\cdots+\frac{c_n}{\beta^n} \tag{7.4} \end{equation} \(c_j\) (\(j=1,2,\cdots,n\)) は \(\beta\) 進表現の \(j\) 桁めの数で、\(0\) から \(\beta-1\) までの整数。 ただし式(7.4)で1桁めの数が \(0\) であってはおかしいので、\(c_1\not=0\) とする。 これを「正規化された表現」という。
- 仮数部は \(\log_{10}(2^{23+1})\approx7.22\) 桁で
- 指数部は \(2^{(2^{8-1}-1)}\approx10^{38.23}\) の桁まで
丸め、丸め誤差
浮動小数点数では限られたビット数の仮数部を用いて数を表現することになるから、これより多い仮数部、例えば無限個の仮数部を使わないと表現できないような実数は「近似的」にしか表現できなくなる。 これによって生じる誤差を「表現誤差」という。 例えば10進数の \(0.1\) を2進数で表現しようとすると \begin{equation} 10^{-1}=\frac{1}{2^4}+\frac{1}{2^5}+\frac{0}{2^6}+\frac{0}{2^7}+\frac{1}{2^8}+\frac{1}{2^9}+\frac{0}{2^{10}}+\frac{0}{2^{11}}\cdots \tag{7.5} \end{equation} の通り、無限個の仮数部が必要になってしまう。 この際、仮数部の最下位より1つ下の桁に対して「切り捨て」や「四捨五入」(2進数だと「0捨1入」)といった操作を施して、有効な桁数に収めるという操作が行われる。 こうした操作を総称して一般に「丸め (round-off)」と呼んでいる。
情報落ち、桁落ち
計算機の中の演算にあたって、とりわけ加減算は要注意である。 これは演算に際して「情報落ち」や「桁落ち」と呼ばれる現象を引き起こす可能性があるからである。
2 | . | 0 | 0 | 0 | 0 | 0 | |||
+ | ) | 0 | . | 0 | 0 | 0 | 0 | 0 | 1 |
2 | . | 0 | 0 | 0 | 0 | 0 | 1 |
情報落ちが発生する代表的な場面とは、多数の数を足し合わせる操作である。 この授業で今後扱う数値積分 (第9章) や常微分方程式の初期値問題 (第10章) がよくある例。 また第1章で分散や標準偏差を「プログラミング向け」の式 \begin{equation} {\sigma_y}^2=(\overline{y^2})-(\overline{y})^2 \tag{1.7} \end{equation} で計算する際においても、平均 \(\overline{y}\) と標準偏差 \(\sigma_y\) の絶対値が大きく異なるような場合には情報落ちに注意が必要である。
これに対して「桁落ち」とは、値のほぼ等しい数の差を計算するようなときに発生する現象である。 例えば、有効数字6桁で表わされている2つの実数 \(\sqrt{1001}\approx31.6386\) と \(\sqrt{1000}\approx31.6228\) の差を計算すると \begin{equation} \sqrt{1001}-\sqrt{1000}\approx31.6386-31.6228=0.0158 \tag{7.7} \end{equation} となり、答の有効数字は3桁に低下してしまう。 すなわち桁落ちとは、結果の絶対値が小さくなるような計算の結果、その分だけ有効数字が減り、相対誤差が大きくなってしまう現象のことである。
こうした問題を避けるための大事な方法は、情報落ちや桁落ちを生じにくい式を用いて計算 すること。 例えば分散を計算する際であれば、式(1.7)と \begin{equation} {\sigma_y}^2=\frac{1}{N}\sum_{i=1}^{N}(y_i-\overline{y})^2 \tag{1.5} \end{equation} という数学的に全く等価な式が2つあったのだが、2つの式の違いはまさに情報落ちに対する安全さにある。 式(1.5)では「平均 \(\overline{y}\) からのずれ」にのみ注目することによって情報落ちを抑えようとしており、そのため正確な値が求まりやすくなっている。