ニアです、こんにちはー!
今回は浮動小数点型の数値がメモリ上でどのように格納されているか、調べていきます。
#1. バイトオーダー(エンディアン)とは
その前に、バイトオーダーについて簡単に説明します。
バイトオーダーとは、2バイト以上の数値をメモリ上に格納する時の並び順です。例えば「0x01020304」という4バイトの数値がある時、メモリ上に「0x01 0x02 0x03 0x04」と上位バイトから順に格納する方式をビッグエンディアンといい、「0x04 0x03 0x02 0x01」と下位バイトから順に格納する方式をリトルエンディアンといいます。
C言語やC++では、数値型とunsigned char型配列(要素数は数値型のデータサイズ(バイト単位))で構成した共用体を使って、メモリ上での並び順を調べることができます。
以下はint型の数値からメモリ上での並び順を見るプログラムです。
#include <stdio.h>
int main( int argc, char* argv[] ) {
union { int i; unsigned char b[4]; } ib;
int i;
ib.i = 0x01020304;
printf( "元の値 : %08X\n", ib.i );
printf( "メモリ上での並び順 : " );
for( i = 0; i < 4; i++ ) {
printf( "%02X%c", ib.b[i], i < 3 ? ' ' : '\n' );
}
return 0;
}
◆ 実行結果
※使用したコンピューターのCPUはIntel Core-i5 2520M(バイトオーダーはリトルエンディアン方式)です。
元の値 : 01020304
メモリ上での並び順 : 04 03 02 01
#2. 浮動小数点型の値のメモリ上での並び
ここからが本題、浮動小数点型の値はメモリ上でどのように格納されているのか、float型を例に調べていきます。
float型変数1つと要素数が4個のunsigned char型配列、int型変数1つ(内部表現の値を確認するため(→ 浮動小数点数の内部表現を取得してみよう))で構成した共用体を使います。
#include <stdio.h>
int main( int argc, char* argv[] ) {
union { float f; int i; unsigned char b[4]; } fb;
int i;
fb.f = 1.024f;
printf( "元の値 : %f\n", fb.f );
printf( "内部表現の値 : %08X\n", fb.i );
printf( "メモリ上での並び順 : " );
for( i = 0; i < 4; i++ ) {
printf( "%02X%c", fb.b[i], i < 3 ? ' ' : '\n' );
}
return 0;
}
◆ 実行結果
※使用したコンピューターのCPUはIntel Core-i5 2520M(バイトオーダーはリトルエンディアン方式)です。
元の値 : 1.024000
内部表現の値 : 3F83126F
メモリ上での並び順 : 6F 12 83 3F
実行結果を見ると、float型の数値はメモリ上で「0x6F 0x12 0x83 0x3F」と、内部表現の値「0x3F83126F」の下位バイトから順に並んでいることが分かります。
つまり、浮動小数点型の数値はその内部表現の値をバイトオーダーに従って、メモリ上に格納されます。
実数値をバイナリデータとして扱う時に、参考になれば幸いです。
それでは、See you next time!