С.И.Хашин
Класс совсем простой, поэтому cpp-файл отсутствует, все лежит в dispers.h:
class dispers {
public:
double sum, sum2;
int cnt;
// constructors/destructor
dispers(void) {sum=sum2=cnt=0;}
void add(double v) { sum+=v; sum2+=v*v; cnt++;}
void clear(void) {sum=sum2=cnt=0;}
double mid(void) { return cnt==0? 0 : sum/cnt; }
double off(void) { return cnt==0? 0 : sqrt(sum2/cnt - dSquare(sum/cnt)); }
};
Допустим, что у нас имеется некоторый набор чисел:
x[0], x[1], ..., x[N-1].
Будем считать, что N велико, например, несколько миллиардов и числа читаются из файла последовательно.
Для нахождения mid среднего этих чисел, их не обязательно запоминать все, достаточно хранить только сумму прочитанных чисел sum и их количество cnt. Тогда в любой момент мы можем сказать, что среднее прочитанных чисел равно mid = sum/cnt.
А как узнать среднеквадратичное отклонение чисел x[i] от среднего?
Можно прочитать файл два раза, после первого прохода найти среднее значение mid, а после второго среднее отклонение от mid.
Но тоже самое можно сделать за один проход:
dispers di;
for( int i=0; i<N; i++ ) di.add(x[i]);
printf(" mid = %f\n", di.mid());
printf(" mid offset = %f\n", di.off());