浮動小数点
現在、CSの勉強のために、コンピュータアーキテクチャ (電子情報通信レクチャーシリーズ)を読んでいる。
P.5
この式で、実数が表せることに関して、即座に理解できなかったので、浮動小数点に関して、自分なりにまとめてみた。
実数とは
まず、言葉の定義の復習。実数とは、有理数と無理数の総称である。
反対に、実数でないものは、虚数(2i, 3-4i等)が挙げられる。
(前提)コンピュータでの数字の取り扱い
コンピュータでは、「0」と「1」の2進数で数字を表現する。2進数の負の数に関しては、2の補数を用いる。
そして、小数に関しては、浮動小数点を用いる。(小数点の位置をあらかじめ決めておく、固定小数点という方法もある。)
浮動小数点
浮動小数点は、小数点の位置を固定せずに表現された数である。小数点を固定しないことで、非常に大きな数から、非常に小さな数まで表すことができる。
小数点の位置を固定せずに表現するため、10進数の指数表記のような形で表現する。
10進数の場合、基数を10として、0〜9の数字で仮数を表現する。そして、浮動小数点数の場合、基数を2として、0,1の数字で仮数を表現する。(上の図では、わかりやすいように、指数を10進数で表現しているが、指数に関しても2進数表記する必要がある。)
そして、浮動小数点にはいくつかの表し方があるようで、ここではIEEE754規格に準拠した32ビット単精度浮動小数点について扱う。
IEEE754の単精度で表現
10進数の「-78.39」 を IEEE754の単精度で表現する。
符号は、負の数なので「1」とする。
次に、整数と小数で分割して、2進数に変換する。
78.39 = 78 + 0.39
78の整数の部分は、2で割っていき、余りを計算する。
78 / 2 = 39 余り0 39 / 2 = 19 余り1 19 / 2 = 9 余り1 9 / 2 = 4 余り1 4 / 2 = 2 余り0 2 / 2 = 1 余り0 1 / 2 = 0 余り1
2で割れなくなったところで、下から読む。
78(10) = 1001110(2)
0.39の小数の部分は、小数部分に2をかけていき、1以上の場合は、1とする。1以下の場合は、 0とする。
0.39 * 2 = 0.78 0.78 * 2 = 1.56 0.56 * 2 = 1.12 0.12 * 2 = 0.24 0.24 * 2 = 0.48 0.48 * 2 = 0.96 0.96 * 2 = 1.92 0.92 * 2 = 1.84 0.84 * 2 = 1.68 0.68 * 2 = 1.36 0.36 * 2 = 0.72
ほとんどの場合、小数部分の計算は無限に続く。
0.39(10) = 0.011000111101011100...(2)
2進数に変換した整数部分と小数部分を足し合わせる。
78.39(10) = 1001110.011000111101011100...(2)
小数点の位置を移動させる。
78.39(10) = 1.001110011000111101011100... * 2^6 (2)
指数部は、6
なので、バイアス値127を足す。
6 + 127 = 133 133(10) = 10000101(2)
仮数部は、「1.」の部分を無視する。仮数部は、23桁しかいれることができないので、丸める必要がある。IEEE754のRN (Round to the Nearest)方式は、最近接偶数方向丸めと呼ばれる、2つの桁(23桁目と24桁目)を使って判断する方法を採用している。
- 00 → 00
- 01 → 00
- 10 → 10
- 11 → 100
00111001100011110101110 | 0001010... # 23桁と24桁は、00 なので、そのまま 00 とする 00111001100011110101110
以上から、78.39 を浮動小数点数の単精度で求めると、符号部、指数部、仮数部を合わせて、以下のように表せる。
1 10000101 00111001100011110101110
まとめ
浮動小数点について、これまできちんと理解できていなかったと思えた。今回の復習を通して、少し浮動小数点について理解を深めることができた。
浮動小数点の場合、丸め誤差が発生しており、近似計算であることを意識し、結果の精度(誤差)も考えるようにしていきたい。