メモリ内の浮動小数点数の格納フォーマット


細部が成否を決める
転入先http://blog.csdn.net/bingxuewujian/article/details/6437657
一つのプログラムから始まる
 
[cpp]  viewplain copy
#include   
using namespace std;  
int main(int argc, char* argv[])  
{  
    float a = 1.0f;//浮動小数点数はメモリに記号+指数+末尾数で保存されています    cout<<(int&)a<    int b = 0x3f800000;  
    cout<
    cout<<(int)a<
    return 0;  
}  
 
前例:1.0の浮動小数点の形式で、メモリにはこのように保存されています.
   00111111 1000 00000000 0000 0000 0000
シンボル部分:0(ピンクの背景);
指数部:127+0=127(黄色の背景)
下付き部分:0(青の背景)
10進数に変換:106535216
 
--------------------------------------------------------------------------------------------------------------------------------------
 
浮動小数点数にはfloatとdoubleの2種類があり、floatは32ビット、doubleは64ビットを占めています.そのバイナリストレージフォーマットはIEEE 754規格に従う.floatを例にとると:
      
符号ビット:正数0、負数1
float型データ123.456を例に、そのバイナリストレージフォーマットを分析します.
まず、10進数123.456をバイナリ数1111011.01110101111001に変換します.
(そのうち0.456はどのようにバイナリに変換しますか?絶えず2に乗って整頓して、順番に並べます
たとえば、0.734375はバイナリを回転し、結果は101111です.
         0.734375 x 2 = 1.46875          0.46875 x 2 = 0.9375          0.9375 x 2 = 1.875          0.875 x 2 = 1.75          0.75 x 2 = 1.5          0.5 x 2 = 1.0) 
 
1111011.01110101111001すなわち1.11101101110101111001に2を乗じた6乗
まずこれは正数であり、シンボルビットは0であり、
ステップコードは6ですが、シフトコードに変換します.
(どのように6のシフトコードを求めますか?ここでも私はあまり深く研究していません.私はみんなが直接6+127=133で、2進数に変えて100000101になります)
(シフトコードと補コードの関係:[X]シフトと[X]補の関係はシンボルビットが互いに逆数である(シンボルビットのみが異なる))
端数は1.11101110101111001の小数部、すなわち
11101101110100101111001 
以上、123.456のバイナリ・ストレージ・フォーマットは、01000010111101101110100101111001です.
 
------------------------------------------------------------------------------------------------------
浮動小数点数:浮動小数点型変数はコンピュータメモリに4バイト(Byte)、すなわち32-bitを占有する.IEEE-754フォーマット規格に従う.1つの浮動小数点数は2つの部分からなる:底数mと指数e.
    ±mantissa ×2exponent (数式中のmantissaとexponentは2進数で表されることに注意)この浮動小数点数の実際の値を2進数で表す.指数部分は8ビットの2進数を占有し、数値範囲は0-255であることを表すことができる.指数は正と負であるべきであるため、IEEEは、ここで算出した次数は127を減算しなければならないことが真の指数であると規定している.したがってfloatの指は数は-126から128までの底数部分が実際には24-bitの1つの値を占有することができ、その最上位は常に1であるため、最高ビットは記憶されず、記憶には23-bitしかない.これまで,基数部23ビットに指数部8ビットを加えて31ビットを用いた.では、floatは4バイトの32-bitを占めていると前に言ったように、もう一人は何に使っているのでしょうか.もう1つは、実は4バイトの中の最上位で、浮動小数点数の正負を示すために使用され、最上位が1の場合、負数、最上位が0の場合、正数である.
浮動小数点データは、次の表の形式で4バイトに格納されます.
    Address+0Address+1 Address+2 Address+3
Contents SEEEEE EMMMMMMMMMMMMMMMMMMMMMMMMMS:浮動小数点数の正負を表し、1は負数、0は正数E:指数に127を加えた値の2進数M:24-bitの底数(23-bitのみ格納)
注意:ここには特例があり、浮動小数点数が0の場合、指数も底数も0ですが、これまでの式は成立しませんでした.2の0次が1なので、0は特例です.もちろん,この特例も干渉するとは思わず,コンパイラは自動的に認識する.
例1:コンピュータ記憶中のバイナリ数が実際の浮動小数点数にどのように変換されるかについては、上記の形式で説明する.以下に、コンピュータに記憶されている具体的なデータを例に挙げる.Address+0 Address+1 Address+2 Address+3
Contents 0 xC 10 x 48 0 x 000 x 00次に、上記のデータが-12.5であるかどうかを検証し、変換プロセスも確認します.
浮動小数点数は直接フォーマットで格納されていないため、いくつかの部分から構成されているので、浮動小数点数を変換するには、まず各部分の値を分離します.
   Address+0 Address+1 Address+2Address+3
フォーマットSEEEEE EMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
バイナリ11000001 01001000 0000000000
16進C 14800
表示:
S:1で、負数です.
E:100000010から10進数130-127=3、すなわち実指数部3.
M:10010000000000000です.ここでは,素数の左に1つの1を省略して格納し,実際の素数を用いて1億10000000000億と表示する.
ここで、3つの部分の値を持ち出しましょう.今、指数部分Eの値で底数部分Mの値を調整します.調整方法は、指数Eが負の場合、底の小数点が左にシフトし、指数Eが正の場合、底の小数点が右にシフトする.小数点移動の桁数は、指数Eの絶対値によって決まる.
ここで、Eは正3で、右に3をシフトするとすぐに:1100.100000000000から次のようになります.この結果、12.5のバイナリ浮動小数点数になります.彼を10進数に換算すると12.5になります.どのように変換するか、以下を見てください.
小数点左の1100は(1)× 23) + (1 ×22) + (0 × 21) + (0 × 20)の結果は12であった.
小数点の右側の.100...は(1)× 2-1) +(0 × 2-2) + (0 × 2-3) + ... ,結果は.5です.
以上の2値の和は12.5であり、Sは1であるため、負の数、すなわち−12.5として用いられる.
したがって、16進0 XC 1480000は浮動小数点数-12.5である.
例2:浮動小数点数をコンピュータ記憶形式のバイナリ数に変換する.例えば17.625をfloat型に換算する.まず、17.625をバイナリビットに換算します:10001.101(0.625=0.5+0.125、0.5=1/2、0.125=1/8小数部をバイナリに変換しない場合は、他の書籍を参照してください)さらに10001.101を左に移動し、小数点の前に1.0001101 x 2の4回しか残っていません(左に4ビット移動したため).このとき、私たちの基数Mと指数Eが出てきました.   M, 1, IEEE , 0001101 。
    E, 4, 127, 131, 10000011 
    S, , S 0.


以上、17.625のfloatストレージフォーマットは、
 
   0 10000011 00011010000000000000000
16進法に変換:0 x 41 8 D 00
だから、floatは見ると4バイトも占めています.
****************************************************************
doubleはメモリに保存され、doubleは8バイト64ビットで、そのうち最上位63ビットはシンボルビットで、1はこの数が負で、0が正であることを示す.62-52位で、全部で11位が指数位です.51-0位で52位が末尾位です.
例3:IEEE浮動小数点数表現に従い、double型浮動小数点数38414.4を16進コードに変換する.
整数部と小数部を処理する:整数部を直接16進数:960 Eにする.小数の処理:0.4=0.5*0+0.25*1+0.125*1+0.0625*0+......実際にはこれは永遠に計算できません!これが有名な浮動小数点数精度の問題です.したがって、前の整数部を加えて53ビットとすればよい(隠しビット技術:最上位の1はメモリに書き込まない).辛抱強く、手作業で53ビットまで計算すれば、38414.4(10)=10010110000001110.0110101010101010010101010010010101(2)科学記数法は1.001......に2を乗じた15回である.指数は15!そこで次数コードを見ると、合計11ビットで、範囲は-1024~1023と表すことができる.指数は負であることができるため、計算を容易にするために、規定はすべて先に1023を加えて、ここで、15+1023=1038.バイナリ表示:100 00001110シンボルビット:正-0!合計(末尾バイナリ最上位1不要):01000000 11100010 11000001 11001101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101
バイトの逆順で格納される16進数は、55,55,55 CD C 1 E 240です.