3

浮動小数点数について知りたいと思ったことよりも多くのことを学んでいます。

追加する必要があるとしましょう:

1 10000000 00000000000000000000000

1 01111000 11111000000000000000000

2の補数形式。

最初のビットは符号、次の8ビットは指数、最後の23ビットは仮数です。

科学的記数法に変換せずに、これら2つの数値を加算するにはどうすればよいですか?ステップバイステップでそれを歩くことができますか?

このようなもののための良いリソースはありますか?ビデオと練習例は素晴らしいでしょう。

4

1 に答える 1

6

同じ指数になるように数値をスケーリングする必要があります。次に、仮数フィールドを追加し、必要に応じて結果を正規化します。

そうそう、それらが異なる符号の場合は、代わりに減算関数を呼び出すだけです:-)

わかりやすいので、10進数で例を見てみましょう。さらに、小数点以下8桁で格納されていると仮定します(数値は0から1までです)。

2つの数値を追加します。

sign  exponent  mantissa  value
   1        42  18453284  + 0.18453284 x 10^42
   1        38  17654321  + 0.17654321 x 10^38

これらの数値を最大の指数にスケーリングすると、仮数フィールドを追加できるものが得られます。

sign  exponent  mantissa  value
   1        42  18453284  + 0.18453284 x 10^42
   1        42      1765  + 0.00001765 x 10^42
   =        ==  ========
   1        42  18455049  + 0.18455049 x 10^42

そして、あなたはあなたの番号を持っています。これは、シフトによって精度が失われる可能性があることも示しています。たとえば、IEEE754単精度浮動小数点数は次のようになります。

1e38 + 1e-38 = 1e38

など:

#include <stdio.h>
int main (void) {
    float f1 = 1e38;
    float f2 = 1e-38;
    float f3 = f1 + f2;
    float f4 = f1 - f3;
    printf ("%.50f\n", f4);
    return 0;
}

オーバーフローで何が起こるかという点では、それは私が述べた正規化の一部です。99999.9999に追加しましょう99999.9993。それらはすでに同じ指数を持っているので、スケーリングする必要はありません。したがって、次を追加するだけです。

sign  exponent  mantissa  value
   1         5  99999999  + 0.99999999 x 10^5
   1         5  99999993  + 0.99999999 x 10^5
   =        ==  ========
   1         5 199999992  ???

ここでは、キャリーの状況があるため、8桁に制限されているため、そのキャリーを数字に入れることができないことがわかります。次に、キャリーを挿入できるように、数値を右にシフトします。そのシフトは事実上10による除算であるため、それに対抗するために指数をインクリメントする必要があります。

それで:

sign  exponent  mantissa  value
   1         5 199999992  ???

になります:

sign  exponent  mantissa  value
   1         6  19999999  + 0.19999999 x 10^6

実際には、最も近い数値に丸める必要があるため、単純な右シフトではありません。シフトアウトする数が5以上の場合は、左側の数字に1を加える必要があります。そのため99999.9993、2番目の番号として選択しました。私が自分自身に追加99999.9999した場合、私は次のようになっていたでしょう:

sign  exponent  mantissa  value
   1         5 199999998  ???

これは、右シフトで、左に向かってかなりの数のキャリーをトリガーします。

sign  exponent  mantissa  value
   1         6  20000000  + 0.2 x 10^6
于 2011-10-25T03:27:30.267 に答える