我有一段代码如下:
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个小数位呢?)。
答案 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位扩展精度格式计算。所以,它会给出很多数字,但只计算其中一些数字。