2013年3月22日金曜日

float、double、IEEE、不思議の国のアリス

【参考】1,2,3,4,,


浮動小数点方式で小数を表現する場合、
32ビット使う方法(=IEEEの単精度float型
64ビット使う方法(=IEEEの倍精度double型
がある。
ちなみにint型32ビット符号付整数、long型64ビット符号付整数である。

単精度を例にとる。

32ビット=符号部S(1)+指数部E(8)+仮数部M(23)


によって、

(-1) S × 1.M (2) × 2 E-127


を表現する。仮数部の「1.M」という形を正規化という。
0 ≦ E ≦ 254 ∴ -127 ≦ E - 127 ≦ 127 なので、
「1.M」を元にして小数点が左右に127ずつフワフワ動く感じ。

ここでめっちゃちっこい数(0に近い数)を考えてみる。

それは E = 0 のときで、1.0...00 (2) × 2 -127
その次に小さい数は、 1.0...01 (2) × 2 -127
その差は、        0.0...01 (2) × 2 -127-150

刻みが-150ごとの定規なのに、最初の刻みだけ、0から-127の場所にある、ってこと。

これは、

目盛りが1mmごとの定規なのに、最初の目盛りは、0から8388608 mm = 8.4 km の場所にある

ってこと。馬鹿みたい。
この定規は、進んだ距離が2倍になると、目盛り幅も2倍になる、という性質をもつ。
たぶん、アリスの不思議の国あたりにある。「浮動」っていうのもチェシャ猫っぽい。
もし何かの刑罰で、
「〇目盛り進むまで決して休んではならない」みたいなルールでこの定規を歩かされたら、
かなり精神的に「くる」のは間違いない。

このままだと、-127より0に近い数は、アンダーフローで0化するので計算に支障が出る。
そこで、

32ビット=符号部S(1)+指数部E(8)+仮数部M(23)


によって、

(-1) S × 1.M (2) × 2 E-127


ただし、E = 0ならば、

(-1) S × 0.M (2) × 2 -126

を表すことにする。仮数部の「0.M」という形を正規化という。

現在これらの仕様は、IEEE754 2008として策定されている。

なお、

非正規数が発生すると、演算が遅くなるらしい。
floatは計算時にはdoubleに変換されるので、特に速度メリットはないらしい。格納メモリは半分で済むけど。

0 コメント:

コメントを投稿