乱数の例題 †C と C++ とで乱数の例題を書いてみる。 C の標準ライブラリに含まれている rand() 関数、及びその初期値を与える srand() 関数を使って、実数で 0.0 から 1.0 の範囲の一様乱数を 100個作って 標準出力に打ち出す。 srand() の引数(乱数の seed )の型は unsigned int である。 この値で、これ以降に呼ばれる rand() が発生する乱数列が決まる。 同じ値を与えれば、同じ乱数列が生成されるので debug などの場合には便利である。 一方、起動する毎に異なる乱数列にしたい場合は、ここで示す ように time() 関数を使う手法がよく用いられる。time() 関数は現在時刻を time_t 型 の値として戻す。この time_t 型は通常は unsigned long 型が用いられる。 ここでは型の不一致を防ぐため unsigned int に cast している。 rand() 関数は 0 から RAND_MAX までの一様乱数を int 型で返す関数である。 0 と RAND_MAX は含まれる。 RAND_MAX を 1.0 に対応させるべきか、RAND_MAX + 1 を 1.0 に 対応させるべきか議論の余地があるが、 ここでは RAND_MAX + 1 を 1.0 に対応させる。 なお、以下のプログラム中で (double)(RAND_MAX + 1) とせずに、 (double)RAND_MAX + 1.0 としているのは、RAND_MAX + 1 が integer overflow を起こす可能性を 考慮しているためである。 /* randtest.c */ #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int i; double r; srand((unsigned int)time(0)); for(i = 0; i < 100; i++) { r = ((double)rand()) / ((double)RAND_MAX + 1.0); printf("%lf\n", r); } return 0; } C++ で書いてみる /* randtest.cpp */ #include <iostream> #include <cstdlib> #include <ctime> int main() { int i; double r; std::srand((unsigned int)std::time(0)); for(i = 0; i < 100; i++) { r = ((double)std::rand()) / ((double)RAND_MAX + 1.0); std::cout << r << std::endl; } return 0; } |