2010-06-02 3 views
0

Я должен сообщить среднее значение входящих чисел, как я мог это сделать, не используя какую-либо структуру данных, чтобы отслеживать все значения, а затем вычислять среднее значение, суммируя их и деля на число значений?Усреднение увеличения числа переменных

+0

http://stackoverflow.com/questions/895396/how-do-i-find- в среднем-в-большом-множестве чисел – PRR

ответ

1

Сохраните текущую сумму и считайте. Обновите оба для каждого входящего номера.

avg = sum/count. 
+0

Это может быть одно простое решение, но я не могу использовать этот простой метод из-за ограниченной точности чисел с плавающей запятой. У меня есть огромное количество чисел, поступающих каждую секунду, поэтому сумма станет очень большим числом, и некоторые ошибки с плавающей запятой произойдут ... – Oscar

+0

@Oscar: тогда вы должны указать это ограничение в своем вопросе. Как бы то ни было, ваш вопрос не очень сложный! –

+0

@ Dan: Это хорошо известная проблема с усреднением чисел с плавающей запятой и должна учитываться почти всегда, когда вы суммируете большие количества чисел. – Joey

1

Просто продолжайте работать и сколько цифр вы получили, это все, что вам нужно для вычисления среднего.

1

Если у вас есть номера a[1] a[2] ... a[n] и вы знаете, их среднее значение avg(n) = (a[1] + ... + a[n])/n, то когда вы получаете другой номер a[n + 1] вы можете сделать:

avg(n + 1) = (avg(n) * n + a[n + 1])/(n + 1)

Некоторые ошибки с плавающей запятой неизбежны, но вы должны проверить это и посмотрим, достаточно ли это.

Чтобы избежать переполнения, вы могли бы сделать разделение первой:

avg(n + 1) = (avg(n)/(n + 1)) * n + (a[n + 1]/(n + 1))

1

Если я не ошибаюсь полностью, можно вычислить avg(n+1) также таким образом:

avg(n+1) = (a[1]+ ... + a[n+1])/(n+1) = 
     = (a[1]+ ... + a[n])/(n+1) + a[n+1]/(n+1) = 
     = (n(a[1]+ ... + a[n])/n)/(n+1) + a[n+1]/(n+1) = 
     = n*avg(n)/(n+1) + a[n+1]/(n+1) = 

     = n/(n+1) * avg(n) + a[n+1]/(n+1) 

так размножаются старый avg на n/(n+1) и добавьте новый элемент, деленный на n+1. В зависимости от того, как высоко n получит и насколько большой ваши ценности, это может уменьшить ошибки округления ...

EDIT: Конечно, вы должны рассчитать n/(n+1) с помощью поплавков, в противном случае она всегда будет оказывать 0 ...

0

вам не нужно, чтобы отслеживать общую сумму, только счетчик:

class Averager { 
    float currentAverage; 
    size_t count; 
    float addData (float value) { 
     this->currentAverage += (value - this->currentAverage)/++count; 
     return this->currentAverage; 
    } 
} 

from->prevent long running averaging from overflow?