2

我有一段代码如下:

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

val1 和 val2 都是 long double。

问题来自这样一个事实,即结果是:

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

这没有任何意义。看来 val2 没有被添加到 val1,但是,显然有足够的信息可以添加到它的小数val1部分val2

我被难住了,有人有什么想法吗?

我相信我正在使用 GCC 4.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(因为加法产生的差异超出了二进制长双精度格式的表示范围)

于 2012-08-31T16:37:37.157 回答
4

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

于 2012-08-31T16:33:59.353 回答