IEEE754浮動小数点数のデコード/エンコード
また、妙な方向に脱線中です。
MSDNを眺めていたら、便利な関数を発見しました。
float ldexp( float x, // 浮動小数点値。 int exp // 整数の指数。 ); ldexp 関数は x * 2 の exp 乗の値を返します。
C89から存在する関数のようですが、全然知りませんでした。
これを使えば、
float make_float( int exp, // 指数(バイアス=127) long frac) // 仮数(を2の23乗した値) { return std::ldexp(static_cast<float>(frac), exp-(127+23)); }
として浮動小数点数を簡単に合成できます。
逆に、floatから指数と仮数を取得するのはこの関数です。
float frexp( float x, // 浮動小数点値。 int * expptr // 指数部を示す整数の格納場所を指すポインタ。 ); frexp は、仮数部を返します。 frexp 関数は、浮動小数点値 (x) を仮数部 (m) と指数部 (n) に分割します。 m の絶対値が 0.5 以上で 1.0 未満になり、x = m*2n になるようにします。
これを使えば、指数と仮数に分解するのも簡単です。
void split_float( float f, int& exp, // 指数(バイアス=127) long& frac) // 仮数(を2の23乗した値) { frac = static_cast<long>(std::ldexp(std::frexp(f, &exp), 23+1)); exp += (127-1); }
frexp()の返す仮数が0.5以上1.0未満なので、指数/仮数を一つずらす必要があります。
まだ、0や無限、NaNの処理が抜けていますが、まぁ大体こんな感じです。
std::numeric_limits