Manpages

名 前

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 >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE

説 明

rand() 関 数 は 0 以 上 RAND_MAX 以 下 (数 学 的 に 書 く と [0, RAND_MAX]) の 範 囲 の 疑 似 乱 数 整 数 を 返 す 。

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

rand() 関 数 は 再 入 可 能 (reentrant) で は な い 、 つ ま り ス レ ッ ド セ ー フ で は な い 。 こ の 関 数 に は 隠 し 状 態 が あ り 、 呼 び 出 さ れ る 度 に こ の 隠 し 状 態 が 変 更 さ れ る か ら で あ る 。 ち ょ う ど こ の 隠 し 状 態 が 次 の 呼 び 出 し 時 の 乱 数 の 種 と し て 使 わ れ る よ う な も の で あ る 。 実 際 に は も う 少 し 複 雑 か も し れ な い が 。 ス レ ッ ド を 使 用 す る ア プ リ ケ ー シ ョ ン で 再 現 可 能 な 動 作 を さ せ た い 場 合 に は 、 こ の 状 態 を 明 示 的 に 指 定 で き な け れ ば な ら な い 。 こ れ を 行 う に は 、 再 入 可 能 な rand_r() 関 数 を 使 用 す る 。

rand() と 同 様 、 rand_r() は [0, RAND_MAX] の 範 囲 の 疑 似 乱 数 整 数 を 返 す 。 seedp 引 き 数 は 、 rand_r() の 呼 び 出 し 間 で 状 態 を 保 持 す る た め に 使 用 さ れ る unsigned int へ の ポ イ ン タ ー で あ る 。 seedp が 指 す 整 数 に 同 じ 初 期 値 を rand_r() を 呼 び 出 し 、 呼 び 出 し 間 で そ の 値 が 変 更 さ れ な け れ ば 、 同 じ 疑 似 乱 数 系 列 が 得 ら れ る 。

rand_r() の seedp 引 き 数 が 指 す 値 に よ り 提 供 さ れ る 状 態 は 非 常 に 小 さ な 空 間 な の で 、 こ の 関 数 は 弱 い 疑 似 乱 数 生 成 器 に な っ て し ま う 。 代 わ り に 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 に 由 来 す る 。 POSIX.1−2008 は 、 rand_r() を 廃 止 予 定 と し て い る 。

注 意

rand() と srand() の Linux C Library 版 は 、 random(3)srandom(3) の 両 関 数 と 同 じ 乱 数 生 成 ア ル ゴ リ ズ ム を 使 用 し て い る 。 そ の た め 、 下 位 の ビ ッ ト は 上 位 の ビ ッ ト と 同 じ く ら い に ラ ン ダ ム で あ る 。 し か し 、 旧 版 の rand() の 実 装 や 、 他 の シ ス テ ム の 現 在 の 実 装 で は 、 下 位 の ビ ッ ト が 上 位 の ビ ッ ト ほ ど ラ ン ダ ム に な っ て い な い 。 移 植 性 を 高 め る 場 合 で も 、 精 度 の 高 い 乱 数 が 必 要 な ア プ リ ケ ー シ ョ ン で は こ の 関 数 は 使 用 し て は い け な い (代 わ り に random(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 int seed) {
next = seed; } 以 下 の プ ロ グ ラ ム を 使 う と 、 特 定 の 乱 数 の 種 が 与 え ら れ た 場 合 に rand() が 生 成 す る 疑 似 乱 数 系 列 を 表 示 す る こ と が で き る 。

#include <stdlib.h>
#include <stdio.h>

int
main(int argc, char *argv[])
{
int j, r, nloops;
unsigned int seed;

if (argc != 3) {
fprintf(stderr, "Usage: %s <seed> <nloops>\n", argv[0]);
exit(EXIT_FAILURE); }

seed = atoi(argv[1]);
nloops = atoi(argv[2]);

srand(seed);
for (j = 0; j < nloops; j++) {
r = rand();
printf("%d\n", r); }

exit(EXIT_SUCCESS); }

関 連 項 目

drand48(3), random(3)

こ の 文 書 に つ い て

こ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。