如何缓存某个列表中所有浮点值的求和,避免精度错误?
例子
我有许多物理形状的质量:m1
,m2
,m3
,...
这些形状组合成一个质量很大的物体 M
= m1
+m2
+m3
+....
我必须经常请求大体的质量,所以我缓存了M
。
现在,我有责任适本地更新 M
。
当我添加质量 = mi
的形状时:-
M += mi;
当我移除质量 = mi
的形状时:-
M -= mi;
问题
程序添加/删除形状一段时间后,
M
离正确求和的距离越来越远。 (m1
+m2
+m3
+....)
结果,我的程序终于执行异常了。
毫无疑问,如果某对mi
和mj
的质量比非常低或非常高,则症状会更快出现。
问题
如何专业地缓解这个数字问题?
换句话说:-
我应该永远不要缓存总和 M
吗?
在添加/删除一个小形状之后,或者(可能)在一些调用者请求 M
之前,我是否应该每次(以蛮力方式)重新计算总和?
我已阅读 https://en.wikipedia.org/wiki/Kahan_summation_algorithm , 只能推迟问题。
最佳答案
如果您知道质量的范围,您可以考虑使用定点算法,并使用int64_t
,这将为您提供 19.5 位的精度,并且只要您永远不会溢出,加法和减法可以按任何顺序进行并且始终精确。
关于c++ - 加法/减法(质量)的精度误差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40199983/