c++ - 四舍五入的平均值越来越差
问题描述
我正在尝试使用 Arduino 对来自高度传感器的读数进行平均,但随着时间的推移,分辨率变得越来越差,尽管原始输入数据保持不变。
此代码中未明确定义的所有变量都是浮点数。
altTotal = 0.00;
slopeTotal = 0.00;
altitude = ps.readFloatAltitudeMeters();
//=========== Altitude averaging
for (int j = 0.00; j <=(aveNum-2); j++) {
arrAlt[j] = arrAlt[j+1];
}
arrAlt[aveNum-1] = altitude;
for (i = 0.00; i <= (aveNum-1); i++){
altTotal = altTotal + arrAlt[i];
}
altAve = altTotal/(i);
//============
f = f+1;
altRd = altRd + altAve;
if (f == 5) {
//======== check cycle time
unsigned long endCycle = micros();
unsigned long delta = endCycle - start;
delta = delta/1000;
unsigned long start = endCycle;
loop1 = loop2;
loop2 = delta;
loopTime = loop2-loop1;
//========
v0 = v1;
v1 = v2;
v2 = altRd/f - v0 - 2*v1;
altButt = v0 + 2*v1 + v2;
alt1 = alt2;
alt2 = altButt;
climbRate = (alt2 - alt1) * (1000/loopTime); //to convert climb rate to m/s
//climbRate = -5;
f = 0;
altRd = 0;
}
我希望“climbRate”的输出具有一致的分辨率,但随着时间的推移,分辨率会变得更糟,是 2 的倍数。首先它以 0.006 的分辨率开始,然后是 0.012,然后是 0.023,然后是 0.047,然后是 0.094,以此类推。
以下是输出示例:
0.000,m/s ,0,0.10,328ms ,0.00m altRd ,1603.11m altButt
0.000,m/s ,0,0.10,328ms ,1603.12m altRd ,1603.11m altButt
0.000,m/s ,0,0.10,328ms ,3206.23m altRd ,1603.11m altButt
0.000,m/s ,0,0.10,328ms ,4809.35m altRd ,1603.11m altButt
0.000,m/s ,0,0.10,328ms ,6412.46m altRd ,1603.11m altButt
0.023,m/s ,0,0.10,328ms ,0.00m altRd ,1603.12m altButt
0.023,m/s ,0,0.10,328ms ,1603.12m altRd ,1603.12m altButt
0.023,m/s ,0,0.10,328ms ,3206.24m altRd ,1603.12m altButt
0.023,m/s ,0,0.10,328ms ,4809.37m altRd ,1603.12m altButt
0.023,m/s ,0,0.10,328ms ,6412.51m altRd ,1603.12m altButt
0.047,m/s ,0,0.10,328ms ,0.00m altRd ,1603.13m altButt
0.047,m/s ,0,0.10,328ms ,1603.14m altRd ,1603.13m altButt
0.047,m/s ,0,0.10,328ms ,3206.28m altRd ,1603.13m altButt
0.047,m/s ,0,0.10,328ms ,4809.42m altRd ,1603.13m altButt
0.047,m/s ,0,0.10,328ms ,6412.55m altRd ,1603.13m altButt
我不确定问题出在哪里。
我将一些变量设置为不同的类型,但我将它们全部转换为浮点数以尝试提高分辨率但没有成功。
解决方案
鉴于上面的示例,我无法告诉您错误的确切位置,但我可以告诉您导致问题的原因以及解决问题的方法。
您的代码在数值上不稳定。与大多数其他语言一样,实数值在 C++ 中通过浮点表示(引入了一个新的更准确的标准,但尚未广泛使用)。
float
值精度为 23 位,这意味着其精度约为其值的 10^{-7}。下面的所有内容都被截断。
例如:2e7f + 1 == 2e7f
是true
因为 1 太小给定浮点精度。
很可能在您的代码中的某个地方,您需要两个越来越大的浮点变量的差异,导致它们的差异随着时间的推移越来越不准确。
要修复它,您可以使用double
而不是float
. 如果你不能,或者这还不够,那么你必须使你的代码在数字上更稳定......它可能很复杂......这不是可以在简短的答案中轻松解释的东西。寻求有关该问题的教程。
推荐阅读
- php - 使用 Google Slides API 更新形状的渐变背景
- openshift - 更新 JenkinsX 预览别名导致部署失败并出现“ImagePullBackOff”错误
- php - 非数组的数组式访问(真、假、空等)
- css - 找不到适合此布局的 flexbox
- asp.net-core - asp.net core 2.2 发布请求未到达端点
- apache - XAMPP 错误:启动 Apache 服务时遇到错误(Apache 意外关闭)
- json - Swift:有办法快速调试可解码对象
- c++ - 如何修复无效的 API 密钥、IP 或操作权限错误?
- java - 为什么我的实例变量没有被@Inject 初始化为null?
- php - 将数字添加到foreach循环php