サイコロ #6
擬似乱数の生成にdSFMT ver.2.2を使用して実験してみる。
せっかくなのでSSE2を使用するコードを生成させ、
周期はたぶんデフォルトのDSFMT_MEXP=19937を指定する。
まず、#1のルールにしたがって、一億回ダイスを振ってみる。
dice1.c
#include <stdio.h> #include "dSFMT.h" int main(void) { const int seed = 13579; const unsigned int N = 100000000; dsfmt_t dsfmt; unsigned int i, x, c[6], s; double e; for (i = 0; i < sizeof(c) / sizeof(c[0]); i++) c[i] = 0; dsfmt_init_gen_rand(&dsfmt, seed); for (i = 0; i < N; i++) { x = dsfmt_genrand_close_open(&dsfmt) * 6; c[x]++; } s = 0; for (i = 0; i < sizeof(c) / sizeof(c[0]); i++) { printf("%u ", c[i]); s += c[i]; } printf("%u\n", s); e = 0; for (i = 0; i < sizeof(c) / sizeof(c[0]); i++) e += (double)c[i] / s * i; printf("%f\n", e); return 0; }
dSFMTのソースコード自体はC99としてコンパイルする必要があるが、
そのヘッダファイルdSFMT.hはC89のソースの一部としてインクルードできた。
各得点の回数はunsigned intでカウントしているが、
試行回数のN(=100000000)もunsigned intなのでオーバーフローの心配はないはず。
実行する。
$ ./dice1 16667460 16671961 16667210 16666741 16664688 16661940 100000000 2.499751
一行目は0から5までそれぞれ得点した回数とその総計(=1億)、
二行目は得点の平均値である。
#1で示した通り、得点0から5までのそれぞれが約1/6で発生しており、
一億回分の得点の平均値は約2.5になっている。