总和超过循环浮点数的允许值

时间:2015-07-03 13:50:25

标签: c++ optimization error-correction

我最近创建了这个简单的程序来找到平均速度。

平均速度=Δx/Δt

我选择x作为t的函数为 x = t^2

因此 v = 2t

另外, avg v = (x2 - x1) / (t2 - t1)

我选择间隔 t = 1s to 4s 。意味着 x来自1 to 16

因此 avg v = (16 - 1) / (4 - 1) = 5

现在程序:

#include <iostream>

using namespace std;
int main() {
    float t = 1, v = 0, sum = 0, n = 0;  // t = time, v = velocity, sum = Sigma v, n = Sigma 1
    float avgv = 0;

    while( t <= 4 ) {
        v = 2*t;
        sum += v;
        t += 0.0001;
        n++;
    }
    avgv = sum/n;
    cout << "\n---->  " << avgv << "  <----\n";
    return 0;
}

我使用非常小的时间增量来计算很多时刻的速度。现在,如果 t 的增量为0.001,则计算出的平均值为4.99998 现在,如果我将 t 的增量设为0.0001,则平均值变为 5.00007

进一步减少增量至0.00001产生平均值v = 5.00001

为什么会这样?

谢谢。

1 个答案:

答案 0 :(得分:0)

在基数2 0.00010.001是周期性数字,因此他们没有精确的表示。其中一个被四舍五入,另一个被四舍五入,所以当你总结很多时,你会得到不同的价值。

这与十进制表示中的情况相同,如果您选择相应数字的数字(假设每个变量可以包含3个十进制数字)。 比较:

a = 1 / 3; // a becomes 0.333
b = a * 6; // b becomes 1.998

使用:

a = 2 / 3; // a becomes 0.667
b = a * 3; // b becomes 2.001

两者都应该(理论上)导致2但由于舍入误差会产生不同的结果

在十进制系统中,由于10被分解为素数25,因此只有分母可以被25整除的分数可以是用有限数量的十进制数字表示(所有其他分数是周期性的),在基数2中,只有具有2的幂的分母的分数可以精确地表示。尝试使用1.0/512.01.0/1024.0作为循环中的步骤。另外,请注意,如果您选择的步骤太小,则可能没有足够的数字来表示float数据类型中的数字(即使用double s)