如何在级数计算的总和中达到最大精度?
How to achieve maximal accuracy in the sum of series calculation?
我写了一个代码来计算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;
}
非常感谢任何建议and/or帮助。
嗯,我觉得pow先用底数,指数,像这样,也记得-i:
for (i=1; i<=n; i++)
sum += pow(2,-i);
声明sum时可以用double代替float,这样更准确(double比float使用更多的位数来表示十进制数,所以精度更高)
要查看更精确的输出,您需要请求比 C++ 默认值更高的精度。一种方法是:
#include <iomanip>
…
std::cout << std::setprecision(99);
接下来,考虑这段代码:
for (i=1; i<=n; i++)
sum += 1.0/pow(2,i);
首先,认识到 pow
实施的质量各不相同。 C 和 C++ 标准对浮点运算的质量松懈,一些 pow
实现 return 的结果与数学结果略有不同,例如 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
来生成更准确的值。如果 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);
我写了一个代码来计算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;
}
非常感谢任何建议and/or帮助。
嗯,我觉得pow先用底数,指数,像这样,也记得-i:
for (i=1; i<=n; i++)
sum += pow(2,-i);
声明sum时可以用double代替float,这样更准确(double比float使用更多的位数来表示十进制数,所以精度更高)
要查看更精确的输出,您需要请求比 C++ 默认值更高的精度。一种方法是:
#include <iomanip>
…
std::cout << std::setprecision(99);
接下来,考虑这段代码:
for (i=1; i<=n; i++)
sum += 1.0/pow(2,i);
首先,认识到 pow
实施的质量各不相同。 C 和 C++ 标准对浮点运算的质量松懈,一些 pow
实现 return 的结果与数学结果略有不同,例如 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
来生成更准确的值。如果 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);