RAND

Section: Linux Programmer's Manual (3)
Updated: 2007-07-26
Index JM Home Page roff page
 

名前

rand, srand - 乱数を生成する関数  

書式

#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 || _XOPEN_SOURCE  

説明

rand() 関数は 0 から RAND_MAX の間の疑似乱数整数を返す。

srand() 関数は、 rand() 関数で作られる疑似乱数整数系列の新しい種として、 その引き数の値を使用する。 これらの関数を使用して作られた疑似乱数系列は、 同じ値を引き数として srand() を呼ぶことで、 再現することが可能である。

種の値が与えられない場合には、 rand() 関数は 自動的に 1 を種とする。

rand() 関数は再入可能 (reentrant) ではない、つまりスレッド・セーフではない。 なぜなら、この関数は隠し状態を持っており、呼び出される度に変更するからである。 ちょうどこの隠し状態が次の呼び出し時の乱数の種として使われるようなものである。 実際にはもう少し複雑かもしれないが。スレッドを使用するアプリケーションで 再現可能な動作をさせたい場合には、この隠し状態が原因で再現性がなくなる。 rand_r() 関数は unsigned int 型の変数へのポインタを引き数にとり、 この変数を状態格納用に使用する。 状態数が非常に小さいので、この関数はあまりよい擬似乱数生成器とは言えないだろう。 代わりに drand48_r(3) を使うとよい。  

返り値

rand() と rand_r() 関数は 0 と RAND_MAX の間の数を返す。 srand() 関数は値を返さない。  

準拠

関数 rand() と srand() は SVr4, 4.3BSD, C89, C99, POSIX.1-2001 に準拠している。 関数 rand_r() は POSIX.1-2001 に由来する。  

注意

rand() と srand() の Linux C Library 版は、 random(3) と srandom(3) の両関数と同じ乱数生成 アルゴリズムを使用している。そのため、下位のビットは上位のビットと 同じくらいにランダムである。 しかし、旧版の rand() の実装や、他のシステムの現在の実装では、下位のビットが上位のビットほど ランダムになっていない。移植性を高める場合でも、精度の高い乱数が必要な アプリケーションではこの関数は使用してはいけない。

Numerical Recipes in C: The Art of Scientific Computing (William H. Press, Brian P. Flannery, Saul A. Teukolsky, William T. Vetterling; New York: Cambridge University Press, 1992 (2nd ed., p. 277)) では、次のようなコメントがなされている。

「1 と 10 の間の乱数を生成したいのであれば、常に

j = 1 + (int) (10.0 * rand() / (RAND_MAX + 1.0));

のように上位ビットを用いること。

j = 1 + (rand() % 10);

のような、下位のビットを用いるような方法は決してしないこと。」

乱数の生成は複雑な話題である。前述の Numerical Recipes in C では実用的な乱数生成を論点とした優れた議論が第 7 章 (乱数) で展開されている。

より理論的な議論については Donald E. Knuth の The Art of Computer Programming, volume 2 (Seminumerical Algorithms), 2nd ed.; Reading, Massachusetts: Addison-Wesley Publishing Company, 1981 の第 3 章 (乱数) を見よ。ここでは、 たくさんの実用的な話題についても深く網羅されている。  

POSIX 1003.1-2003 では、 rand() と srand() の実装例として以下を挙げている。これは、異なる2つのマシンで同じ乱数系列が 必要な場合には便利であろう。

    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;
    }
 

関連項目

drand48(3), random(3)


 

Index

名前
書式
説明
返り値
準拠
注意
関連項目

This document was created by man2html, using the manual pages.
Time: 04:31:57 GMT, November 19, 2007