#include <stdlib.h> int rand(void); int rand_r(unsigned int *seedp); void srand(unsigned int seed);
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
rand_r(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
srand() 関数は、 rand() 関数で作られる疑似乱数整数系列の新しい種として、 その引き数の値を使用する。 これらの関数を使用して作られた疑似乱数系列は、 同じ値を引き数として srand() を呼ぶことで、 再現することが可能である。
種の値が与えられない場合には、 rand() 関数は 自動的に 1 を種とする。
rand() 関数は再入可能 (reentrant) ではない、つまりスレッド・セーフではない。 なぜなら、この関数は隠し状態を持っており、呼び出される度に変更するからである。 ちょうどこの隠し状態が次の呼び出し時の乱数の種として使われるようなものである。 実際にはもう少し複雑かもしれないが。スレッドを使用するアプリケーションで 再現可能な動作をさせたい場合には、この隠し状態が原因で再現性がなくなる。 rand_r() 関数は unsigned int 型の変数へのポインタを引き数にとり、 この変数を状態格納用に使用する。 状態数が非常に小さいので、この関数はあまりよい擬似乱数生成器とは言えないだろう。 代わりに drand48_r(3) を使うとよい。
static unsigned long next = 1; /* RAND_MAX を 32767 と仮定 */ int myrand(void) { next = next * 1103515245 + 12345; return((unsigned)(next/65536) % 32768); } void mysrand(unsigned seed) { next = seed; }