有没有办法找到比sum()/ N"更好"的算术平均值?

may*_*eye 19 language-agnostic algorithm math

假设我们有N个数字(整数,浮点数,你想要的任何东西),并希望找到它们的算术平均值.最简单的方法是将所有值相加并除以值的数量:

def simple_mean(array[N]): # pseudocode
    sum = 0
    for i = 1 to N
       sum += array[i]
    return sum / N
Run Code Online (Sandbox Code Playgroud)

它工作正常,但需要大整数.如果我们不希望大整数和我们都是罚款舍入误差,N是两个电源,我们可以使用"分而治之": , ((a+b)/2 + (c+d)/2)/2 = (a+b+c+d)/4, ((a+b+c+d)/4 + (e+f+g+h)/4)/2 = (a+b+c+d+e+f+g+h)/8等等.

def bisection_average(array[N]):
   if N == 1: return array[1]
   return (bisection_average(array[:N/2])+bisection_average(array[N/2:]))/2
Run Code Online (Sandbox Code Playgroud)

还有其他方法吗?

PS.懒惰的游乐场

Jas*_*n S 30

Knuth列出了以下计算给定浮点的平均值和标准差的方法(原版在计算机程序设计艺术第1卷第232页,1998版;我的改编在下面避免了第一次迭代的特殊套管):

double M=0, S=0;

for (int i = 0; i < N; ++i)
{
    double Mprev = M;
    M += (x[i] - M)/(i+1);
    S += (x[i] - M)*(x[i] - Mprev);
}

// mean = M
// std dev = sqrt(S/N) or sqrt(S/N+1)
// depending on whether you want population or sample std dev
Run Code Online (Sandbox Code Playgroud)


sep*_*p2k 17

这是一种仅使用整数计算均值而无需舍入误差并避免大中间值的方法:

sum = 0
rest = 0
for num in numbers:
  sum += num / N
  rest += num % N
  sum += rest / N
  rest = rest % N

return sum, rest
Run Code Online (Sandbox Code Playgroud)

  • C不会使用单个函数或运算符公开div/mod,但是如果同时使用这两个函数或运算符,大多数好的编译器都会生成指令/调用. (2认同)
  • @Stephen:_"C不会使用单个函数或运算符公开div/mod"_ - 除非我们计算[`div`](http://en.cppreference.com/w/c/numeric/math/div ),这正是如此 - 虽然不适用于花车 (2认同)

Sve*_*lov 3

如果大整数有问题...可以吗

a/N + b/N+.... n/N
Run Code Online (Sandbox Code Playgroud)

我的意思是您只是在寻找其他方法还是最佳方法?

  • 为什么?!?!如果 a、b 等是整数,这会给你一个错误的答案。如果它们是浮点数,我不确定,但我的预感是,与仅执行求和然后除法相比,您会得到更多的舍入误差。在任何一种情况下,计算时间都会大大增加,但其好处却值得怀疑。 (2认同)