简体   繁体   English

如何在 c++ 中添加两个大的双精度数

[英]How to add two large double precision numbers in c++

I have the following piece of code我有以下一段代码

#include <iostream>
#include <iomanip>

int main()

{
    double  x = 7033753.49999141693115234375;
    double  y = 7033753.499991415999829769134521484375;
    double z = (x+ y)/2.0;

    std::cout  << "y is " << std::setprecision(40) << y << "\n";
    std::cout  << "x is " <<  std::setprecision(40) << x << "\n";
    std::cout  << "z is " << std::setprecision(40) << z << "\n";

    return 0;
}

When the above code is run I get,当上面的代码运行时,我得到,

y is 7033753.499991415999829769134521484375
x is 7033753.49999141693115234375
z is 7033753.49999141693115234375

When I do the same in Wolfram Alpha the value of z is completely different当我在 Wolfram Alpha 中做同样的事情时,z 的值完全不同

 z = 7033753.4999914164654910564422607421875 #Wolfram answer

I am familiar with floating point precision and that large numbers away from zero can not be exactly represented.我熟悉浮点精度,并且无法准确表示远离零的大数。 Is that what is happening here?这就是这里发生的事情吗? Is there anyway in c++ where I can get the same answer as Wolfram without any performance penalty?无论如何,在 c++ 中,我可以得到与 Wolfram 相同的答案而没有任何性能损失吗?

large numbers away from zero can not be exactly represented.远离零的大数不能精确表示。 Is that what is happening here?这就是这里发生的事情吗?

Yes.是的。

Note that there are also infinitely many rational numbers that cannot be represented near zero as well.请注意,还有无限多的有理数也不能在零附近表示。 But the distance between representable values does grow exponentially in larger value ranges.但是可表示值之间的距离确实在较大的值范围内呈指数增长。

Is there anyway in c++ where I can get the same answer as Wolfram...无论如何在 c++ 中我可以得到与 Wolfram 相同的答案...

You can potentially get the same answer by using long double .使用long double可能会得到相同的答案。 My system produces exactly the same result as Wolfram.我的系统产生的结果与 Wolfram 完全相同。 Note that precision of long double varies between systems even among systems that conform to IEEE 754 standard.请注意,即使在符合 IEEE 754 标准的系统之间, long double的精度也会因系统而异。

More generally though, if you need results that are accurate to many significant digits, then don't use finite precision math.更一般地说,如果您需要精确到许多有效数字的结果,则不要使用有限精度数学。

... without any performance penalty? ...没有任何性能损失?

No. Precision comes with a cost.不,精确是有代价的。

Just telling IOStreams to print to 40 significant decimal figures of precision, doesn't mean that the value you're outputting actually has that much precision.只是告诉 IOStreams 打印到 40 个有效的小数位精度,并不意味着您输出的值实际上具有那么高的精度。

A typical double takes you up to 17 significant decimal figures (ish);一个典型的double最多需要 17 个有效小数位(ish); beyond that, what you see is completely arbitrary.除此之外,您所看到的完全是任意的。

Per eerorika's answer, it looks like the Wolfram Alpha answer is also falling foul of this, albeit possibly with some different precision limit than yours.根据 eerorika 的回答,看起来 Wolfram Alpha 的答案也违反了这一点,尽管可能与您的精度限制不同。

You can try a different approach like a "bignum" library, or limit yourself to the precision afforded by the types that you've chosen.您可以尝试不同的方法,例如“bignum”库,或者将自己限制在您选择的类型所提供的精度范围内。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM