実数の表現
コンピューターでは整数や実数を0と1の組み合わせで扱っている。ルールは一般的に用いられているIEEEなんちゃらというのを知っておけば良いらしい。
単精度実数は全部で32bitで、内訳は
符号[1bit] + 指数部[8bit] + 仮数部[23bit]
倍精度実数は全部で64bitで、内訳は
符号[1bit] + 指数部[11bit] + 仮数部[52bit]
となっている。
以下、単精度の9.1を例に変換方法を述べる。
<符号>
符号は正のとき0, 負のとき1.
今回は0.
<指数部>
指数部は十進数AをA = a * 2**nと表記したとき、aの整数部が1となる最小のnのこと。A=9.1であれば9.1 = 1.1375 * 2**3であるからn=3となる。ここで指数部の範囲は-127~128と決められているので、3は次のように変換される。
3 -> 3+127 = 130 = 2**7 + 2**1 = 2#10000010
この8桁の数列が指数部。ここで2#は二進数表記であることを表す。
<仮数部>
元の数を指数部と仮数部に分けたとき、仮数部は1.1375のように整数部が必ず1となる。これは既知なので無視して、次のように変換していく。すなわち2倍したとき1以上となれば1, そうでなければ0を二進数表記の数字に加えていく。もちろん1を超えた後は1を引いて同様に続ける。
0.1375 * 2 = 0.275 0
0.275 * 2 = 0.55 0
0.55 * 2 = 1.1 1
0.1 * 2 = 0.2 0
0.2 * 2 = 0.4 0 *
0.4 * 2 = 0.8 0
0.8 * 2 = 1.6 1
0.6 * 2 = 1.2 1 *
0.2 * 2 = 0.4 0
...
スター部分が循環小数。つまり9.1の仮数部は
0010 0011 0011 0011 ...
である。単精度では23桁なので、24桁目で四捨五入(というか零捨一入)する。
0010 0011 0011 0011 0011 001[1]
1だから切り上げて
0010 0011 0011 0011 0011 010
これが仮数部。
各部分が得られたので統合する。
01000001000100011001100110011010
見づらい。。
部分ごとに分けると
0 10000010 00100011001100110011010
1byteごとに分けると
01000001 00010001 10011001 10011010
<endian>
big endianとlittle endianで格納の順番が異なる。
big endianはそのままだったはず。
little endianは右から1byteずつ並べるので次のようになる。
10011010 10011001 00010001 01000001