2種類の浮動小数点形式 IEEE754とPDP

そこらへんの/usr/include/float.hにある浮動小数点データの指数の最大値・最小値は、単精度だとこうなっている。

#define FLT_MIN_EXP     (-125)
#define FLT_MAX_EXP     128

何故正と負でこんなに差があるのかという解説*1


理由を一言で言うと、「Cの浮動小数点モデルはPDP-11の浮動小数点形式に由来するが、実際に動いているCPUはIEEE754に従った浮動小数点形式を処理するから」である。

どちらの形式も、単精度32ビットの内訳は、符号1ビット、指数部8ビット、仮数部23ビットであるが、指数部と仮数部の意味づけが異なる。
異なるのは、仮数部をどのように正規化するかで、IEEE754では1以上2未満にするが、PDPだと0.5以上1未満になる。実際の仮数部表現では最上位の1のビットを省略するところは同じなので、有効数値桁はどちらも23ビット全体。他にも指数部の下駄がIEEE754だと127、PDPは128と異なるが今回の話とは関係ない。


Cの規格書の「5.2.4.2.2 Characteristics of floating types 」をみると、仮数部は0.5以上1未満になることがわかる。浮動小数点数仮数部と指数部に分解する関数frexpで得られる仮数部も実際にその範囲になっている。つまり、CはPDP型の浮動小数点形式をベースにしている。UnixPDP上で誕生したという経緯があり、過去からの互換性を守るためであろう。


本題に戻って、実際にIEEE754で使える仮数部は00000000は±0か非正規化数、11111111は±∞か非数なので、00000001から11111110であり、下駄が127なので-126から+127になる。仮数部1で指数が-126〜+127というのを、仮数部0.5にすると指数は-125〜+128になり、冒頭の結果となる。

*1:某Q&Aサイトでした回答の再構成