C言語でのライブラリ関数を用いた乱数生成

rand() 関数の使用

rand() 関数は、stdlib.hで定義されている関数で、0 から RAND_MAX の間の疑似乱数整数を返します。 この関数を用いて、0より大きくNより小さい一様乱数(実数)を生成するには

((double)rand() / ((double)RAND_MAX + 1)) * N

とすればできます。整数がほしいなら、

(int)(((double)rand() / ((double)RAND_MAX + 1)) * N)

整数が必要で、浮動小数を使うことが気になるのなら、

rand() / (RAND_MAX / N + 1)

としてください。
どちらもNがRAND_MAXにくらべて十分小さいことを仮定しています。

乱数の質

すぐに思いつく方法として

rand() % N

も考えられますが、この方法 (これは 0から N-1までの数を返そうとする)は、乱数の質が低くなることがあるため避けたほうがいいです。 rand() 関数は、長い間、下位のビットがランダムにならない問題があったためです。 すこし古い説明を見ると、rand関数にかえて、random関数を勧めるものも散見されました。

最近の cygwin 上の gcc であれば、Section: Linux Programmer's Manual にあるように

  1. rand関数
  2. random関数

この両関数と同じ乱数生成アルゴリズムを使用しています。そのため、下位のビットは上位のビットと 同じ程度にランダムであるといえます。

ただ、旧版のrand() の実装や、他のシステムの実装では、 下位のビットが上位のビットほどランダムになっていない場合もありえます。 移植性を高める場合でも、精度の高い乱数が必要なアプリケーションではこの関数は使用し ないようにしましょう。

良質な乱数生成方法を実装した関数は多数あるので,研究などで使用する場合はそれらを使用すること。

srand() 関数

srand()関数は、rand()関数で作られる疑似乱数整数系列の新しい種として、 その引数の値を使用します。 この関数を使用して作られた疑似乱数系列は、同じ値を引数に使用してsrand()を呼ぶことによって、 再現することが可能です。 種の値が与えられない場合には、rand()関数は自動的に 1 を種とします。

本当にランダムに乱数を発生したいときは、 srand()を使って、擬似乱数発生器にランダムな初期値を与え てください。よくある乱数の種は、時刻などです。

注意:プログラム中で srand() を2回以上呼んで役にたつことは滅多にありません。 本当にランダムな数を得ようと思って、rand()を呼ぶ前に毎回srand() を呼ぶような真似はぜったいにしてはいけません。

より詳細な情報については、 各関数についての情報(Linux Programmer's Manual)、C言語FAQをみてください。