通常、コンピュータ上で数値計算を行なうときには、全ての10進数を 2進数に変換してから行なう。整数だけでなく、小数(浮動小数点数)を2進数で表 す方法についても理解しておくことで、誤差の発生するしくみが理解できる。
2進小数の小数第1位は、(1/2)1、第2位は(1/2)2、 第3位は(1/2)3……と、重みを掛けたものを足していく。
例として、2進小数0.10101を10進小数に直してみる。
0.1010101 = 1×(1/2)1 + 0 + 1×(1/2)3 + 0 + 1×(1/2)5 = 0.5 + 0 + 0.125 + 0 + 0.03125 = 0.65625
小数点以下が全て0なら終わり
小数点以下の数を2倍する
1の位に1が現れたら2進数側に1を、現れなければ0を書き足す
10進数側の1の位は捨てる
1に戻る
10進小数0.4375を2進小数に直してみる。
10進表記の経過 | 2進変換の経過 | |
---|---|---|
0 | 0.4375 | 0. |
1 | 2倍して0.875 | 0.0 |
2 | 1の位は0なのでそのまま | 0.0 |
3 | 2倍して1.75 | 0.01 |
4 | 1の位が1なので0.75に | 0.01 |
5 | 2倍して1.5 | 0.011 |
6 | 1の位が1なので0.5に | 0.011 |
7 | 2倍して1.0 | 0.0111 |
8 | 1の位が1なので0に | 0.0111 |
9 | 0になっておしまい | 0.0111 |
gccでfloatやdoubleを表現する方法は、IEEE(電気電子学会)754規格に 従っている。
10進数を2進数に直した上で、±1.A×2B という形式に 正規化する。±の部分、1.Aの部分、2Bの部分をそれぞれ、 符号、仮数部、指数部という。これらを1と0の2進値で表すときに 以下のようなビット数割り当てを行なう。ただし、仮数部は1の位にある 1を省略する。また、符号は + なら0、-なら1とする。
符号1ビット、指数部8ビット、仮数部23ビット
符号1ビット、指数部11ビット、仮数部52ビット
floatの指数部を表す数には127を足したもの、doubleの指数部を表す数には 1023を足したものがBとして用いられる。
例として150.5を浮動小数点数の2進数に直してみよう。
0 1 2 3 0 | 1 2 3 4 5 6 7 8 | 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 | 1 0 0 0 0 1 1 0 | 0 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0100 0011 0001 0110 1000 0000 0000 0000 (b) 4 3 1 6 8 0 0 0 (x)
0x43168000は10進数でいえば1125548032で、最初に表そうとした150.5とは かけ離れている。このように、コンピュータで整数を表す場合と 実数を浮動小数点数で表す場合では根本的に表現形式が異なる。 int型とfloat型は(コンピュータにとって)似ても似つかないものと心得る必要が ある。