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

Sum exceeding permissible value in looping floats

本文关键字:许值 循环      更新时间:2023-10-16

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

平均速度=Δx/Δt

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

因此v=2t

此外,平均v=(x2 - x1) / (t2 - t1)

我选择的间隔为t=1s to 4s。意味着x从1 to 16

因此平均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,则计算出的平均值v为4.99998。
现在,如果我将t的增量设为0.0001,则平均值v变为5.00007

进一步降低增量至0.00001产生平均v=5.000001

为什么会这样?

谢谢。

在基数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(