分布はだいたい分かったので、これで擬似乱数を調べてみよう。
100万回行って、得られた回数を100ごとに区切って、度数をみる。
VC2005EEで、rand()で得られた値の特定のビットを拾う。
if(rand() & bit) {
...
bitが1の結果は、
〜100 56000
〜200 24000
〜300 16000
〜400 32000
8000単位だから、125回周期で同じ回数になることがわかる。
しかし、これは予想外だった。
最下位ビットは非常に規則的に並ぶと思っていたから。
いまどき線形合同法じゃないのか。
それ以外に、5、10、14ビット目と、JScriptで0.5との比較でみてみた。
10ビットまではこのグラフで見ても誤差が大きいことが分かる。
では、14ビット目とJScriptではどちらがよいか、標準偏差でみてみた。
変わらないと言っていいだろう。結局同じなのかもしれない。精度もここまでならよいようだ。
#include
#includeusing namespace std;
int play();
void increment(vector& ary, int m); int bit;
void main(int argc, char **argv) {
if(argc != 2) {
cerr << "usage : coin4 bit." << endl;
exit(1);
}
bit = 1 << atoi(argv[1]);
const int N = 10;
vectorcount;
for(int i = 0; i < N; i++) {
increment(count, play());
}
for(int i = 0; i < (int)count.size(); i++) {
cout << (i + 1) * 100 << "," << count[i] << endl;
}
}int play() {
const int n = 10;
int head = 0;
int counter = 0;
while(true) {
counter++;
if(rand() & bit) {
if(++head == n)
return counter;
}
else
head = 0;
}
}void increment(vector
& ary, int m) {
int k = (m - 1) / 100;
int size = (int)ary.size();
if(size <= k) {
ary.resize(k + 1);
for(int i = size; i <= k; i++)
ary[i] = 0;
}
ary[k]++;
}