4

浮動小数点演算ライブラリを実装しようとしていますが、浮動小数点数を減算するアルゴリズムを理解するのに苦労しています。私は足し算をうまく実装しましたが、引き算はその特殊なケースだと思っていましたが、どこかで間違いを犯しているようです。参照用にここにコードを追加しています。多くの自明の機能がありますが、誰かが 100% 理解できるとは思っていません。私が助けてほしいのはアルゴリズムです。浮動小数点数を追加する場合と同じ方法に従いますが、仮数を追加するときに、負の 1 (減算するもの) を 2 の補数に変換してから追加しますか?

それが私がやっていることですが、結果は正しくありません。非常に近いですが、同じではありません。誰にもアイデアはありますか?前もって感謝します!

フロートを追加するためのほぼ同じアルゴリズムを実装し、それが魅力のように機能するので、私は物事がうまくいくと確信しています。

_float subFloat(_float f1,_float f2)
{
unsigned char diff;
_float result;

//first see whose exponent is greater
if(f1.float_parts.exponent > f2.float_parts.exponent)
{
    diff = f1.float_parts.exponent - f2.float_parts.exponent;

    //now shift f2's mantissa by the difference of their exponent to the right
    //adding the hidden bit
    f2.float_parts.mantissa = ((f2.float_parts.mantissa)>>1) | (0x01<<22);
    f2.float_parts.mantissa >>= (int)(diff);//was (diff-1)

    //also increase its exponent by the difference shifted
    f2.float_parts.exponent = f2.float_parts.exponent + diff;
}
else if(f1.float_parts.exponent < f2.float_parts.exponent)
{
    diff = f2.float_parts.exponent - f1.float_parts.exponent;
    result = f1;
    f1 = f2;        //swap them
    f2 = result;

    //now shift f2's mantissa by the difference of their exponent to the right
    //adding the hidden bit
    f2.float_parts.mantissa = ((f2.float_parts.mantissa)>>1) | (0x01<<22);
    f2.float_parts.mantissa >>= (int)(diff);

    //also increase its exponent by the difference shifted
    f2.float_parts.exponent = f2.float_parts.exponent + diff;
}
else//if the exponents were equal
  f2.float_parts.mantissa = ((f2.float_parts.mantissa)>>1) | (0x01<<22); //bring out the hidden bit




//getting two's complement of f2 mantissa
f2.float_parts.mantissa ^= 0x7FFFFF;
f2.float_parts.mantissa += 0x01;



result.float_parts.exponent = f1.float_parts.exponent;
result.float_parts.mantissa = (f1.float_parts.mantissa +f2.float_parts.mantissa)>>1;
                                                //gotta shift right by overflow bits

//normalization
if(manBitSet(result,1))
    result.float_parts.mantissa <<= 1;  //hide the hidden bit
else
    result.float_parts.exponent +=1;

return result;

}
4

2 に答える 2

2

a-b == a+(-b)、および単項マイナスは些細なことなので、バイナリマイナスについても気にしません。

于 2009-02-26T15:56:19.100 に答える
1

加算コードが正しく、減算が正しくない場合、問題はおそらく 2 の補数と加算にあります。

引き算ではなく、2 の補数と足し算をする必要がありますか?

それが問題でなければ、あなたのアルゴリズムに問題があります。私がこのようなことをしたのは久しぶりです。詳細を教えていただけますか?より具体的には、隠しビットとは何ですか?

隠しビットの処理は、減算ではなく加算に適しているように思えます。f2ではなくf1の仮数部に設定する必要があるのでしょうか?または、f2 の代わりに f1 の仮数を否定しますか?

あなたが何を得ているのか、何を期待しているのか、そしてあなたが使用しているアルゴリズムの詳細を知らなくても、それが私ができる最善のことです.

編集:わかりました、コメントの参照を見ました。提供されたコードで失敗していることの 1 つは、正規化です。加算時に、隠しビットがオーバーフローする (仮数を左にシフトし、指数をインクリメントする) か、オーバーフローしません。減算する場合、仮数の任意の部分がゼロになることがあります。10 進数では、0.5E1 と 0.50001E1 を加算することを検討してください。1.00001E1 になり、正規化すると 0.10001E2 になります。0.50001E1 から 0.5E1 を引くと、0.00001E1 になります。次に、仮数を左にシフトし、指数を必要なだけ減分して、0.1E-4 を取得する必要があります。

于 2009-02-26T16:17:55.117 に答える