使用float的系列之和

时间:2012-09-05 00:18:22

标签: c++ floating-point series

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

enter image description here

以两种方式,第一种 - 前锋,第二种 - 后退。为此我做了 -

#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

有人可以解释为什么两种方式之间有区别?

2 个答案:

答案 0 :(得分:10)

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

只需考虑将一笔金额保留在固定的位数即可。例如,保留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

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

答案 1 :(得分:5)

要在汇总数字时提高准确度,请考虑Kahan summation algorithm。与显而易见的方法相比,这显着降低了误差(包括从最小到最大的总和)。