UNIX マシンならば、 man 3 rand でオンライン・マニュアル読んでみよう。 関数 rand() は から RAND_MAX (これは stdlib.h に定義されている) までの整数値を取る、 周期 の数列の各項を順番に 返す1。
乱数の種 (seed) を変更するには、 srand(seed); を実行すれ ば良い。
/* * test-rand.c */ /* * rand() は * BSD では 0 から 2^{31}-1 までの範囲の疑似乱数を返す。 * SYSTEM V では 0 から 2^{15}-1 までの範囲の疑似乱数を返す。 * */ #include <stdio.h> #include <stdlib.h> /* rand(),srand() */ int main() { int i, n; n = 10; printf("start\n"); for (i = 0; i < n; i++) printf("%d\n", rand()); /* seed を 3 にしてやり直し */ srand(3); printf("start (seed=3)\n"); for (i = 0; i < n; i++) printf("%d\n", rand()); /* seed を 1 にしてやり直し (最初と同じになる) */ srand(1); printf("start (seed=1)\n"); for (i = 0; i < n; i++) printf("%d\n", rand()); return 0; } |
ゲームのプログラミングなどでは、システムの時刻を読み取って、 乱数の種となるデータを生成することがよく行なわれる。 シミュレーションをする場合にもそれをしてよいだろうが、 追試が出来るように種を記録しておくべきであろう。
/* * test-rand2.c */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/time.h> int main() { int i, n, myseed; time_t tloc; n = 10; time(&tloc); myseed = tloc; srand(myseed); printf("start (seed=%d)\n", myseed); for (i = 0; i < n; i++) printf("%d\n", rand()); return 0; } |
種を time() で安直に設定するには、 (tloc, myseed などを省略して)
srand((unsigned)time(NULL)); |
に正規化したい場合は RAND_MAX で割算 すればよいだろう2。
/* * test-rand3.c */ /* * rand() は 0 から RAND_MAX までの範囲の疑似乱数を返す。 * ゆえに割算すれば [0,1] の範囲の疑似乱数値を返す。 */ #include <stdio.h> #include <stdlib.h> double drand() { return rand() / (double) RAND_MAX; } int main() { int i, n; n = 10; printf("start\n"); for (i = 0; i < n; i++) printf("%f\n", drand()); return 0; } |
桂田 祐史