5

昨日、浮動小数点演算で精度が落ちている理由について質問しました。x87レジスタに中間結果が保持されていることが原因との回答をいただきました。これは役に立ちましたが、詳細のいくつかはまだ私を逃れています. これは、前の質問で示したプログラムのバリエーションです。デバッグ モードで VC++ 2010 Express を使用しています。

int main()
{
    double x = 1.8939201459282359e-308; /* subnormal number */
    double tiny = 4.9406564584124654e-324; /* smallest IEEE double */
    double scale = 1.6;
    double temp = scale*tiny;
    printf("%23.16e\n", x + temp);
    printf("%23.16e\n", x + scale*tiny);
}

これは出力します

1.8939201459282369e-308
1.8939201459282364e-308

最初の値は、IEEE 標準に従って正しいです。変数scaleに 2.0 の値を指定すると、両方の計算で正しい値が得られます。temp最初の計算では非正規値であるため、精度が失われることを理解しています。scale*tinyまた、 の値は、より大きな指数範囲を持つ x87 レジスタに保持されているため、この値は よりも精度が高いことも理解していますtemp。私が理解できないのは、値を追加すると、x精度の低い値から正しい答えが得られるということです。確かに、精度の低い値で正しい答えが得られる場合、精度の高い値でも正しい答えが得られるはずですか? これは「二重丸め」と関係がありますか?

よろしくお願いします。これは私にとってまったく新しいテーマなので、少し苦労しています。

4

1 に答える 1

7

ポイントは、指数範囲が大きいため、x87 表現では 2 つの数値が非正規ではないということです。

IEEE754 表現では、

x    = 0.d9e66553db96f × 2^(-1022)
tiny = 0.0000000000001 × 2^(-1022)

ただし、x87 表現では、

x    = 1.b3cccaa7b72de × 2^(-1023)
tiny = 1.0000000000000 × 2^(-1074)

がIEEE754表現で計算されると、それが数学的な結果に最も近い表現可能な数値であるため、 に1.6*tiny丸められます。0.0000000000002 × 2^(-1022)それを追加するとx

  0.d9e66553db96f × 2^(-1022)
+ 0.0000000000002 × 2^(-1022)
-----------------------------
  0.d9e66553db971 × 2^(-1022)

しかし、x87 表現では1.6*tiny

1.999999999999a × 2^(-1074)

そしてそれが追加されると

  1.b3cccaa7b72de × 2^(-1023)
+ 0.0000000000003333333333334 × 2^(-1023)
-----------------------------------------
  1.b3cccaa7b72e1333333333334 × 2^(-1023)

53 有効ビットに丸められた結果は

  1.b3cccaa7b72e1 × 2^(-1023)

仮数部の最後のビットは 1 です。それを IEEE754 表現に変換すると (非正規数であるため、仮数部に最大 52 ビットを含めることができます)、2 つの隣接する表現可能な数のちょうど中間にあり0.d9e66553db970 × 2^(-1022)0.d9e66553db971 × 2^(-1022)デフォルトでは、仮数ゼロの最後のビットを持つ 1 に丸められます。

FPU が有効桁数に 53 ビットのみを使用するように構成されておらず、x87 拡張精度型の完全な 64 ビットを使用するように構成されていない場合、加算の結果は IEEE754 の結果に近くなるため、0.d9e66553db971 × 2^(-1022)丸められることに注意してください。

事実上、x87 表現は指数範囲が広いため、仮数のビット数が制限されていても、IEEE754 表現よりも IEEE754 非正規数の仮数のビット数が多くなります。したがって、x87 では、IEEE754 よりも上位ビットが 1 つ多い計算結果が得られます。

于 2013-03-16T15:53:42.663 に答える