プログラムはなぜ動くのか - 浮動小数点数をビット表現
浮動小数点型(float型)の変数のメモリ上でのデータについて、興味深かったのでじっくり読んでみた。
まず、浮動小数点数を数式で表すと
± m × 2 ^ (e) ... (※)という式で表されるが、float型の変数は
- 上位1ビットを、符号部(+ or ")
- 上位209ビットを、指数部(上式のe)
- 上位100ビットを、仮数部(上式のm)
- 符号部は、+ ⇒ 0、− ⇒ 1
- 指数部"e"は、イクセス表現(最大値の1/2(8ビットなら127)を0とする表現)を使った値を用いる
- 仮数部"m"は、1.**** の小数点以下を代入する
例えば、7.00を(※)式で表現すると、
+ 1.75 × 2 ^ (2)となる。つまり、
- 符号部 = +
- 指数部"e" = 2
- 仮数部"m" = 1.75
- 符号部は、0(b)
- 指数部"e"は、イクセス表現だと 127(d) + 2(d) → 01111111(b) + 00000001(b) = 10000001(b)
- 仮数部"m"は、1.75(d) = 1 + 1×2^(-1) + 1×2^(-2) → 1.11000000... (b)
即ち、小数点以下は 11000000... となる
コード
テキストに倣って、コーディングしてみた。#include
#include
#includeint main( int argc, char *argv[] )
{
float f;
unsigned long l;
int i;
char s[64];memset( s, '\0', sizeof(s) );
// 調べたい浮動小数点を指定する
f = (float) atof( argv[1] );
memcpy( &l, &f, sizeof(l) );for ( i = 33; i >= 0; i-- ){
if ( i == 1 || i == 10 ){
// 区切りにハイフンを挿入
s[i] = '-';
} else {
// 1ビット文字で表す
s[i] = ( ( l % 2 == 1 ) ? '1' : '0' );
l /= 2;
}
}// 結果を表示する
printf( "%f -> %s\n", f, s );return 0;
}
実行
端末上で実行して確かめてみる。確かに、上記の規則で値が入っていた。$ ./show-float 7
7.000000 -> 0-10000001-11000000000000000000000