【问题标题】:sum of series using float使用浮点数的系列总和
【发布时间】:2012-08-29 16:09:51
【问题描述】:

我计算了该系列的前 20 个元素 -

有 2 种方式,第 1 次前进,第 2 次后退。为此我做到了-

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

float sumSeriesForward(int elementCount) {
    float sum = 0;
    for (int i = 0; i < elementCount; ++i) {
        sum += (float) 1 / (pow(3, i));
    }
    return sum;
}

float sumSeriesBack(int elementCount) {
    float sum = 0;
    for (int i = (elementCount - 1); i >= 0; --i) {
        sum += (float) 1 / (pow(3, i));
    }
    return sum;
}

int main() {
    cout.precision(30);
    cout << "sum 20 first elements - forward: " << sumSeriesForward(20) << endl;
    cout << "sum 20 first elements - back: " << sumSeriesBack(20) << endl;
}

我得到了 -

sum 20 first elements - forward: 1.5000001192092896
sum 20 first elements - back: 1.5

有人能解释一下为什么这两种方式有区别吗?

【问题讨论】:

  • 使用浮点数对一系列数字求和时,总是先对较小的数求和——基本浮点数 101——40 年前就学会了。
  • @HotLicks :你的意思是它提供了更好的准确性?
  • @URL87 -- 是的。当您添加一个大数字和一个小数字时,您会从小数字中失去意义。先做小数字会使它们变成更大的数字,从而减少重要性的损失。

标签: c++ floating-point series


【解决方案1】:

要提高求和数字的准确性,请考虑使用Kahan summation algorithm。与显而易见的方法(包括从最小到最大的数字相加)相比,这显着减少了错误。

【讨论】:

    【解决方案2】:

    一般来说,浮点数不能准确地表示值。当您对值进行操作时,错误会传播。在您的示例中,当向后计算时,您将小值添加到更大的数字中,到目前为止,小数字的总和很有可能对更大的数字产生影响。另一方面,当您向前计算时,您从大数字开始,而较小的数字对它的影响越来越小。也就是说,在求和时,您总是希望从小到大求和。

    只需考虑将总和保持在固定位数即可。例如,保留 4 位数字并将这些数字从上到下和从下到上相加:

    values   top to bottom   bottom to top
    10.00      10.00            10.01
    0.004      10.00            0.010
    0.003      10.00            0.006
    0.002      10.00            0.003
    0.001      10.00            0.001
    

    浮点数的工作方式相同,使用固定数量的 [二进制] 数字。

    【讨论】:

    • 虽然从下到上打开了将重复的pow() 调用替换为tmp*=3; 的可能性。它仍然可以以另一种方式工作,但是您必须使用初始 pow() 为 tmp 播种,然后每次除以。
    猜你喜欢
    • 1970-01-01
    • 2011-12-15
    • 2012-11-05
    • 1970-01-01
    • 2021-01-09
    • 2012-09-11
    • 2020-06-13
    • 2015-09-09
    • 1970-01-01
    相关资源
    最近更新 更多