浮動小数点数を2で割るアルゴリズムを書いています。数値がすでに正規化されている場合(指数ビットは> 0)、プロセスは非常に簡単だと思います。指数フィールドを1つ減らしてから、その値を元に戻すのが正しいアプローチだと思います。
すでに非正規化されている浮動小数点数を処理する方法を思い付くのに問題があります(指数ビットはすべて0です)。非正規化数とは何かを理解しており、それらを除算することの意味を一般的に理解していると思います。私は別のプログラムを介して作成したアルゴリズムを実行しています。これが私を混乱させる1つのメッセージです。
値0x7fffffを関数に渡すと、3fffffが返されます。この関数は0x400000を返すことになっています。
ここで何が起こっているのか、そしてなぜこれがこの指定された値を返すことになっているのか、私は本当に理解していません。これを試して説明できる人はいますか?なぜこの値を返すことになっているのですか?
非正規化数を処理するための私の最初のアプローチは、小数ビットを1ずつ右シフトする(2で割る)ことでしたが、これは望ましい手順ではないようです。
これが私が持っているものです:
unsigned float_half(unsigned uf) {
unsigned exp = uf & (0x7F800000);
unsigned sign = uf & (0x80000000);
unsigned fract = uf & (0x007FFFFF);
// Check for NaN or infinity
if(exp == 0x7F800000) {
return uf;
}
// Check for denormalized numbers
if(exp == 0x00000000) {
// Need to do something here, not really sure...
return sign | exp | fract;
}
// Check for exponent of 1 (going to a denormalized number changes things)
if(exp == 0x00800000) {
fract = (0x00FFFFFF & uf) >> 1;
return fract | sign;
}
exp--;
exp = exp & (0x7F800000);
return sign | exp | fract;
}