2

次のようなコードのセクションがあります。

std::cerr << val1 << " " << val2 << std::endl;
val1 = val1 + val2;
std::cerr << val1 << std::endl;

val1とval2はどちらもlongdoubleです。

問題は、これの結果が次のとおりであるという事実から来ています。

-5.000000000000722771452063564190e-01 2.710505431213761085018632002175e-20
-5.000000000000722771452063564190e-01

これは意味がありません。val2はval1に追加されていないようですが、追加できる情報の小数部分には明らかに十分な情報がありval1ますval2

私は困惑しています、誰かが何かアイデアがありますか?

私はGCC4.2を使用していると思います。G ++はIEEE四倍精度形式を使用しますか?または、他の何か(80ビットの拡張精度など、この問題を説明します(ただし、なぜ小数点以下18桁以上が表示されるのですか?)。

4

2 に答える 2

5

val1とval2が正しく印刷されている場合、出力は正しいです:-

-5.000000000000722771452063564190e-01 = -5.000000000000722771452063564190 X e^(-1)  //or 10^(-1)

どこ^ denotes to the power of

2.710505431213761085018632002175e-20 =  -5.000000000000722771452063564190 X e^(-20)  //or 10^(-20)

..

Since val1 >> val2 
=> lim (val2/val1 -> 0) (lim is mathematical limit) .... eq (A)

Consider y=val1+val2
=> y= ((val1+val2)/val1)*val1  (rationalizing)
=> y= {(val1/val1)+(val2/val1)} * val1
=> y= {1+val2/val1}*val1
=> y= {1+0}*val1 .........................................From eq (A)
=> y= val1

そのため、出力は-5.000000000000722771452063564190e-01(加算によって生成された差が2進long double形式による表現の範囲外になるため)です。

于 2012-08-31T16:37:37.157 に答える
4

推測する必要があります... long doubleG++では4倍精度形式で格納されているように見えますが、80ビット拡張精度形式を使用して計算されています。したがって、多くの桁が表示されますが、計算されるのはそのうちの一部のみです。

于 2012-08-31T16:33:59.353 に答える