添加long double会在C ++中给出错误的答案

时间:2012-08-31 16:29:36

标签: c++ long-double

我有一段代码如下:

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

val1和val2都是长双。

问题来自于这样的结果:

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

哪个没有意义。似乎val2没有被添加到val1中,但是val1的小数部分显然有足够的信息可以添加val2

我很难过,有人有什么想法吗?

我正在使用GCC 4.2我相信。 G ++是否使用IEEE四倍精度格式?或其他东西(比如80位扩展精度,可以解释这个问题(虽然为什么会出现超过18个小数位呢?)。​​

2 个答案:

答案 0 :(得分: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的原因(因为加法产生的差异超出了二进制长双格式的表示范围)

答案 1 :(得分:4)

好吧,我应该猜到......看起来G ++上的long double存储为四倍精度格式,但是使用80位扩展精度格式计算。所以,它会给出很多数字,但只计算其中一些数字。