乱数の平均を計算する 2 つのアルゴリズムを比較していました。
- 最初のアルゴリズムはすべての数値を合計し、最後にアイテム数で割ります
- 2 番目のアルゴリズムは、反復ごとに平均を計算し、新しいデータを受信したときに結果を再利用します。
ここには革新的なものは何もないと思います。私は数学者ではないので、これら 2 つのアルゴリズムに名前を付けることはできません。
これが私のコードです:
#include <iostream>
#include <iomanip>
#include <cstdlib>
class Average1
{
public:
Average1() : total( 0 ), count( 0 ) {}
void add( double value )
{
total += value;
count++;
}
double average()
{
return total/count;
}
private:
double total;
size_t count;
};
class Average2
{
public:
Average2() : av( 0 ), count( 0 ) {}
void add( double value )
{
av = (av*count + value)/(count+1);
count++;
}
double average()
{
return av;
}
private:
double av;
size_t count;
};
void compare()
{
Average1 av1;
Average2 av2;
double temp;
for ( size_t i = 0; i != 100000000; ++i )
{
temp = static_cast<double>(std::rand()) / static_cast<double>(RAND_MAX);
av1.add( temp );
av2.add( temp );
}
std::cout << std::setprecision(20) << av1.average() << std::endl;
std::cout << std::setprecision(20) << av2.average() << std::endl;
}
int main()
{
compare();
return 0;
}
出力は次のとおりです。
0.50001084285722707801
0.50001084285744978875
違いは確かにdouble
型の精度によるものです。
結局、どの方法がいいの?実際の数学的平均 (またはそれに最も近い) を与えるのはどれですか?