数値の表現

通常、コンピュータ上で数値計算を行なうときには、全ての10進数を 2進数に変換してから行なう。整数だけでなく、小数(浮動小数点数)を2進数で表 す方法についても理解しておくことで、誤差の発生するしくみが理解できる。

小数の2進変換

2進小数から10進小数

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

10進小数から2進小数

  1. 小数点以下が全て0なら終わり

  2. 小数点以下の数を2倍する

  3. 1の位に1が現れたら2進数側に1を、現れなければ0を書き足す

  4. 10進数側の1の位は捨てる

  5. 1に戻る

10進小数0.4375を2進小数に直してみる。

10進表記の経過2進変換の経過
00.43750.
12倍して0.8750.0
21の位は0なのでそのまま0.0
32倍して1.750.01
41の位が1なので0.75に0.01
52倍して1.50.011
61の位が1なので0.5に0.011
72倍して1.00.0111
81の位が1なので0に0.0111
90になっておしまい0.0111

float/doubleへの変換

gccでfloatやdoubleを表現する方法は、IEEE(電気電子学会)754規格に 従っている。

10進数を2進数に直した上で、±1.A×2B という形式に 正規化する。±の部分、1.Aの部分、2Bの部分をそれぞれ、 符号、仮数部、指数部という。これらを1と0の2進値で表すときに 以下のようなビット数割り当てを行なう。ただし、仮数部は1の位にある 1を省略する。また、符号は + なら0、-なら1とする。

float(全32ビット)

符号1ビット、指数部8ビット、仮数部23ビット

double(全64ビット)

符号1ビット、指数部11ビット、仮数部52ビット

floatの指数部を表す数には127を足したもの、doubleの指数部を表す数には 1023を足したものがBとして用いられる。

例として150.5を浮動小数点数の2進数に直してみよう。

  1. 整数部の150(10)を2進数に直すと 10010110b
  2. 小数部の0.5(10)を2進数に直すと 0.1b
  3. よって全体は 10010110.1b
  4. 1.A×2Bの形式にすると 1.00101101b×27
    (2と7は10進表記)
  5. 最初の桁の1を省くと .00101101b×27
  6. よって「符号は+」、 「指数部は7(+127)=134=10000110b」、 仮数部は00101101b」
  7. これを1ビット、8ビット、23ビット、に並べると
    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
    
  8. 4桁毎に区切り直して16進数で読み直すと
    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型は(コンピュータにとって)似ても似つかないものと心得る必要が ある。


目次