メモリにおけるC/C++浮動小数点数の格納方法の詳細

2749 ワード

いずれのデータもメモリには、例えばshort型データ1156のようなバイナリ形式で格納され、そのバイナリ表現形式は10000000、10000000、100である.Intel CPUアーキテクチャのシステムでは、Intel CPUのアーキテクチャが小端モードであるため、10000000(低アドレスユニット)10000000 100(高アドレスユニット)が格納される.しかし、メモリに浮動小数点数をどのように格納しますか?現在、すべてのC/C++コンパイラはIEEEが制定した標準浮動小数点フォーマット、すなわちバイナリ科学表現法を採用している.
バイナリ科学表現法では,S=M*2^Nは主に3つの部分から構成される:シンボルビット+次数符号(N)+末尾数(M).float型データの場合、そのバイナリは32ビットあり、シンボルビット1ビット、階層コード8ビット、末数23ビットである.double型データの場合、バイナリは64ビット、シンボルビット1ビット、階層コード11ビット、末尾52ビットである.
                31        30-23       22-0
floatシンボルビット符号末尾数
                63        62-52       51-0
doubleシンボルビット番号末尾数
符号ビット:0は正、1は負
ステップコード:ここで、ステップコードはシフトコードで表され、float型データについては所定のバイアス量が127であり、ステップコードには正の負があり、8ビットバイナリについては−128−127、double型については−1024−1023、表示範囲は−1024−1023である.例えばfloat型データについては、ステップコードの真の値が2であると127を加える129となり、そのステップコード表現形式は10000010となる.
端数:有効デジタルビット、すなわち部分バイナリビット(小数点以下のバイナリビット)は、Mの整数部分が一定であることを規定するので、この1は記憶されない.
次に、float型データ125.5を標準浮動小数点フォーマットに変換する
125バイナリ表示形式は1111101、小数部はバイナリ1、125.5バイナリは1111101.1、所定の端数の整数部は一定であるため1.1111011*2^6、次数コードは6、127を加えて133となると100000101、端数については整数部1を削除して1111011となり、その後に0を補って23桁にする、11110110000000億ドル
そのバイナリ表現形式は
0 100000101,11110110000000,000,000,000は、メモリに格納されます.
00000000低アドレス
00000000
11111011
01000010高アドレス
逆にバイナリ形式で浮動小数点数を求めるとすると0,100000101,11110110000000,000,000,000,000,000.
符号が0であるため、正数となります.次数は133-127=6、端数は11110110000000、端数は1.1111011である.だからその大きさは
1.1111011*2^6は、小数点を6桁右にシフトして1111101.1を得るが、1111101の十進法は125、0.1の十進法は1*2^(-1)=0.5であるため、その大きさは125.5である.
同様にfloat型データ0.5をバイナリ形式に変換すると
0.5のバイナリ形式は0.1で、正の数の部分を1にしなければならないため、小数点を1桁右にシフトすると1.0*2^(-1)となり、その次数は-1+127=126で01111110となり、端数1.0は整数の部分を除いて0となり、0から23桁の0000000000000000億円を足した場合、そのバイナリ形式は
0 01111110 00000000000000000000000
以上の解析からfloat型データの最大表現範囲は1.11111111111111111*2^127=3.4*10^38であることがわかる
double型データの場合は同様であるが,その階層コードは11ビット,バイアス量は1023,端数は52ビットである.
試験手順:
 
  
/*   2011.10.2*/
#include
using namespace std;
int main(int argc, char *argv[])
{
    float a=125.5;
    char *p=(char *)&a;
    printf("%d
",*p);
    printf("%d
",*(p+1));
    printf("%d
",*(p+2));
    printf("%d
",*(p+3));
    return 0;
}

出力結果:
0
0
-5
66
float型125.5のメモリへの格納方法は、以下の通りである.
00000000低アドレス
00000000
11111011
01000010高アドレス
従って、pおよびp+1が指すユニットについて、格納されたバイナリ数が表す10進数整数は0である.
一方、p+2が指すセルについては、char型のポインタであり、符号付きのデータ型であるため、11111011、符号ビットが1である負数となり、メモリにバイナリが補符号で記憶するため、その真値は-5となる.
p+3が指すセルの場合、01000010は正数であり、その大きさは66である.上記のプログラムの出力結果はその正確性を検証した.