floating-point - 浮点值的数值稳定运行平均值
问题描述
使用 32 位浮点值,如果 - 开始计算时 - 我还不知道我将拥有多少个值(在以下示例中我只是迭代一个向量,那么计算平均值的最佳(数值上最准确)的方法是什么?我会知道库尔特,但假设我最终只知道元素计数)?
例如,我可以做
float result = 0.f;
for(float num: numbers) {
result += num;
}
num /= numbers.size();
但随着结果变大,精度也会变大。使用较小的值,在某些时候result += num;
实际上不会再改变结果。
我可以
float result = numbers[0]
for(int i=1, i<numbers.size(); i++) {
float frac = (i/float(i+1));
result = result * frac + numbers[i] * (1.0f-frac);
}
但似乎我会以这种方式应用累积错误。
有没有更好的方法而不去 64bit double?
解决方案
这类问题最著名的方法是 Kahan Summation。见这里:https ://en.wikipedia.org/wiki/Kahan_summation_algorithm 。假设总和仍然可以表示为单精度浮点数,请在最后进行直除以找到平均值。
另请参阅此答案以进行一些额外的讨论,该讨论要求或多或少相同:如何计算双打的平均值,以使总误差最小?
推荐阅读
- c - 指针星位置
- java - servlet和html之间的交互
- php - php用我的sqli查询而不是对象数组创建数组
- assembly - 在 mips 汇编程序中读取空格分隔的整数
- raspberry-pi - 树莓派摄像头模组V2如何设置焦距?
- php - 如何使用 php ArrayCachePool?
- javascript - 将对象的第一行重组为 javascript 中的名称
- android - Retrofit 为在后台运行的调用返回 HTTP 401
- jupyter-notebook - 打开多个具有不同扩展配置的 jupyter notebook
- sql-server - SQL Server 临时表与不同会话中的键