昨日、浮動小数点演算で精度が落ちている理由について質問しました。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
精度の低い値から正しい答えが得られるということです。確かに、精度の低い値で正しい答えが得られる場合、精度の高い値でも正しい答えが得られるはずですか? これは「二重丸め」と関係がありますか?
よろしくお願いします。これは私にとってまったく新しいテーマなので、少し苦労しています。