ページ 11

乱数関数について

Posted: 2022年11月18日(金) 12:50
by 絵にかいた餅
乱数関数で同じ値が出てしまいます。デバックをすると値がしっかり変わっているのですが出力すると同じ数字が出てしまいます。わかるかたいたら教えてください。

コード:

int nrand(int x) {
	int y;
	srand((unsigned int)time(NULL));
	y = rand() % x + 1;
	return y;
}

int main() {
	int x;
	int i;
	for (i = 0; i < 100; i++) {
		x = nrand(6);
		printf("%d\n", x);
	}

	return 0;
}

Re: 乱数関数について

Posted: 2022年11月18日(金) 13:23
by usao
> srand((unsigned int)time(NULL));

原因はこれ.
これの場所を main の先頭にでも移して,一度だけやるようにする.

Re: 乱数関数について

Posted: 2022年11月19日(土) 01:59
by 絵にかいた餅
ご回答ありがとうございました。解決しました。

Re: 乱数関数について

Posted: 2022年11月19日(土) 02:40
by 絵にかいた餅
お手数ですがなぜsrandをサブルーチン内にいれてはいけないのか教えていただけると幸いです。

Re: 乱数関数について

Posted: 2022年11月19日(土) 04:07
by みけCAT
srand関数 は、引数の値に基づいてこの後出す乱数の系列を決定します。
この値として秒単位の時刻を与えると、処理は通常1秒に100万回以上実行されるため、
高い確率で毎回同じ値が引数となり、その結果毎回同じ乱数の系列が用いられます。
よって、同じ系列なので、その最初の値も同じとなります。

なお、「サブルーチン内にいれてはいけない」というのは不正確です。
1度だけ実行されるようにする仕組みを入れることで、srandをサブルーチン内に入れても毎回初期化せずに乱数を利用することができます。

コード:

int nrand(int x) {
	static int initialized = 0;
	int y;
	if (!initialized) {
		srand((unsigned int)time(NULL));
		initialized = 1;
	}
	y = rand() % x + 1;
	return y;
}

int main() {
	int x;
	int i;
	for (i = 0; i < 100; i++) {
		x = nrand(6);
		printf("%d\n", x);
	}

	return 0;
}

Re: 乱数関数について

Posted: 2022年11月19日(土) 04:21
by 絵にかいた餅
ご丁寧にありがとうございます。理解できました。