C++ 在C+中,添加长双精度运算会给出错误的答案+;
我有一段代码是这样的:C++ 在C+中,添加长双精度运算会给出错误的答案+;,c++,long-double,C++,Long Double,我有一段代码是这样的: std::cerr << val1 << " " << val2 << std::endl; val1 = val1 + val2; std::cerr << val1 << std::endl; 这没有道理。似乎val2没有添加到val1中,但是,val1的小数部分显然有足够的信息可以添加到val2 我被难住了,有人有什么想法吗 我相信我使用的是GCC4.2。G++是否使用IEEE四倍精度格式?或
std::cerr << val1 << " " << val2 << std::endl;
val1 = val1 + val2;
std::cerr << val1 << std::endl;
这没有道理。似乎val2没有添加到val1中,但是,val1
的小数部分显然有足够的信息可以添加到val2
我被难住了,有人有什么想法吗
我相信我使用的是GCC4.2。G++是否使用IEEE四倍精度格式?或者其他一些东西(比如80位扩展精度,这可以解释这个问题(尽管为什么会显示超过18个小数位?).好吧,我应该猜到了……G++上的长双精度存储为四倍精度格式,但使用80位扩展精度格式进行计算。因此,它会给出很多数字,但只计算了其中的一些数字。如果正确打印val1和val2,则输出正确:-
-5.000000000000722771452063564190e-01 = -5.000000000000722771452063564190 X e^(-1) //or 10^(-1)
其中,^表示的是
2.710505431213761085018632002175e-20 = -5.000000000000722771452063564190 X e^(-20) //or 10^(-20)
这就是为什么输出是
-5.000000000000722771452063564190e-01
(因为加法产生的差异超出了二进制长双精度格式的表示范围)那么val1
和val2
的真正价值是什么?强制性的Goldberg链接:这是在什么架构和操作系统上运行的?我认为e-01
实际上意味着*10^(-01)
@MatthieuM:是的。另外,如果您注意到,四倍精度浮点中可用的精度位数约为35位小数(远远大于两个数字之间19个数量级的差值),这意味着它们应该被添加。然而,正如我在回答中提到的,在G++中,长双精度是用扩展精度数字(精度大约为19位)计算的。此外,你应该检查你的数学…这没有多大意义(除其他错误外,你在这里被零除)。
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