首页 > 解决方案 > 如何在级数求和中达到最大精度?

问题描述

我写了一个代码来计算级数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;
}

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

标签: c++seriesfloating-accuracy

解决方案


要查看更精确的输出,您需要请求比 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. 如果是这样,上面计算的≤ 24的总和没有错误。n

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

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

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

double您可以通过使用而不是生成更准确的值float。如果 IEEE-754 基本 64 位二进制格式用于double,那么这将产生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);

推荐阅读