如何在串联计算的总和中达到最大精度?

时间:2019-04-21 09:24:48

标签: c++ series floating-accuracy

我写了一个代码来计算2 ^(-k)级数的和,但是我不知道如何提高这种计算的准确性。这是我到目前为止所做的。

#include <iostream>
#include <math.h>
using namespace std;

int main()
{
    int i, n;
    float sum = 0;

    cout << "Enter the value of n: ";
    cin >> n;

    for (i=1; i<=n; i++)
        sum += 1.0/pow(2,i);

    cout << "Sum: " << sum;


    return 0;
}

任何建议和/或帮助都非常感谢。

2 个答案:

答案 0 :(得分:0)

要查看更精确的输出,您需要请求比C ++默认值更高的精度。一种方法是:

#include <iomanip>
…
   std::cout << std::setprecision(99);

接下来,考虑以下代码:

for (i=1; i<=n; i++)
    sum += 1.0/pow(2,i);

首先,认识到pow实现的质量各不相同。 C和C ++标准对浮点运算的质量不严谨,某些pow实现对诸如pow(10, 3)之类的简单情况返回的结果与数学结果略有不同。由于pow的实施方式很常见,pow(2, i)可能不会遇到此问题,但应予以考虑。

假设pow(2, i)准确地计算出正确的结果。我们还假设您的C ++实现对float使用了通用的IEEE-754基本32位二进制浮点格式。如果是这样,则上述n≤24的总和中没有没有错误

这是因为每个项1.0/pow(2, i)float的有效位(分数部分)中可以表示为一位,而float的有效位为24位,因此可以连续显示24个连续位。一旦提高了用于格式化输出的精度,n≤24所示的总和就应该准确。

n = 25时,总和不再适合float。此时,通常将使用以下规则将数学结果四舍五入到float中可表示的最接近值:如果两个最接近的可表示值之间有平局,则具有偶数低位的将为选择。这意味着结果将精确为1。对于所有n> 24,结果将为1。

虽然使用float类型,但无法提高精度。这是因为,在可以用float类型表示的所有值中,1是最接近该序列的精确数学和的值。根本就没有可表示的更接近的值,因此任何源代码的计算或更改都不会产生任何更准确的值。

您可以使用double而不是float来产生更准确的值。如果double使用IEEE-754基本的64位二进制格式,那么对于n≤53,将产生精确的结果。对于n> 53,结果将再次为1 ,只有使用扩展精度算法才能改善总和。

另外,请注意:

float sum = 0;
for (i=1; i<=n; i++)
    sum += 1.0/pow(2,i);

在数学上等同于:

float sum = 1 - pow(2.f, (float) -n);

答案 1 :(得分:-1)

嗯,我认为pow首先使用基数,这样的指数也要记住-i:

for (i=1; i<=n; i++)
    sum += pow(2,-i);

您可以在声明sum时使用double而不是float来使精度更高(double使用比float更多的位来表示一个十进制数字,因此精度更高)