平均浮点数时保持精度

Maintain precision when averaging floats

提问人:m81 提问时间:4/22/2015 更新时间:4/22/2015 访问量:673

问:

假设我有大量的浮点数,例如 100 个,我需要计算它们的平均值。

为了得到最准确的结果,我应该将所有数字相加,然后除以 100 吗?

或者我应该将每个数字除以 100,然后将它们全部相加?

(如果重要的话,我正在用 Python 2 编码。

python-2.7 精度 浮点 转换

评论

0赞 MattDMo 4/22/2015
这两个操作完全相同。 与 相同。(a + b + c)/100a/100 + b/100 + c/100
2赞 Ignacio Vazquez-Abrams 4/22/2015
@MattDMo:在无限精确和准确的代数世界中,是的。一旦你把有限的精度和准确性投入到混合中,事情就会开始看起来有点不同。
0赞 Stephen Canon 4/22/2015
@MattDMo:不,他们不是。比较将 100 1/100 (1.0000000000000007) 相加和 100 1 然后除以 100 (1.0) 的结果。
0赞 MattDMo 4/22/2015
@Stephen两者都不完全正确(),那么如何选择使用哪一个呢?0.01
0赞 Stephen Canon 4/22/2015
@MattDMo:将 100 个 1 相加并除以 100 是完全正确的。一般来说,这两种计算都不准确,但在这种情况下是准确的。

答:

3赞 Stephen Canon 4/22/2015 #1

将它们相加,然后除以 100。一个好的经验法则是,您通常可以通过执行较少的操作来最小化FP误差[1]。如果对它们求和然后除法,则已执行 100 次浮点运算。如果先除法再求和,则已执行 199 次浮点运算。

[1] 在一些例外情况下,多次计算的舍入误差会完全抵消,但这很少是偶然发生的——如果发生这种情况,通常是因为算法被设计为由知道自己在做什么的人以这种方式工作。

0赞 Gordon Linoff 4/22/2015 #2

我可以从一般的角度来回答这个问题,而不是从Python的角度来回答这个问题。问题的答案取决于几个因素,包括值的数量和值的范围。

你是对的,将数字加在一起会导致不好的结果。这称为数值不稳定算法。浮点运算会出现问题。在某些时候 x + 1 = x,因为 x + 1 没有表示。

但是,您可能不必担心 100 个数字,除非它们非常大。在处理数百万个数字时,更常出现此问题 - 或者您可能会遇到整数算术的溢出问题。

除以总数也不一定是解决方案,因为你可能在另一个方向上遇到问题——太小了。

一种更稳定的方法是对平均值进行迭代计算:

avg(1) = x1
avg(2) = avg(1) * (1/2) + x2 * (1/2)
avg(3) = avg(2) * (2/3) + x3 * (1/3)
. . .
avg(n) = avg(n - 1) * ((n - 1) / n) + (x(n) / n)

我应该注意的是,如果你的数字范围很广,你仍然会有问题。当您有非常大的正数和负数可以相互抵消时也是如此。在这种情况下,可能必须使用其他方法;这些通常考虑数字的大小和符号。

评论

4赞 Stephen Canon 4/22/2015
如果您担心累积的舍入误差,并且对先验值的分布一无所知,那么最好使用块累积(或 Kahan 求和)而不是迭代平均计算。
0赞 Aristotle Allen 4/22/2015 #3

先加平均值,然后平均值将得到最准确的平均值

如果您对准确性感兴趣,请使用 Decimal