レモン さんが書きました: ↑5年前
それと表示されてく乱数はー1から100に収まってるんですが、最初に表示される数字が約一分ごとに1増えていく感じで乱数になりませんでした。(疑似乱数の弊害ですかね?だとしたら対処法も教えてほしいです。)
<一番最初に表示された数字>
1回目 62
2回目 62
3回目 62
4回目 62
5回目 62
6回目 62
7回目 63
8回目 63
9回目 63
10回目 63
という具合です。2番目以降はぱっと見規則性はなかったです。
time() の値を乱数の種(seed) として、srand() で設定しています。
time() の値は、1970年1月1日からの秒数なので、現在は 15億4千万を
超えた値ですが、プログラムを 10秒に 1回実行しても、乱数の種は
10 しか変わりません。
したがって、rand() による最初の 乱数の値は、あまり差のない値になります。
種を 10ずつ変えて、乱数を 5個ずつ発生させてみましょう。
コード:
#include <stdio.h> // printf, putchar
#include <stdlib.h> // srand, rand
#include <time.h> // time
int main (void)
{
int i, j;
unsigned t = time(NULL);
printf("RAND_MAX = %d\n", RAND_MAX);
for (i = 0; i < 10; i++) {
printf("%10d:", t);
srand(t);
for (j = 0; j < 5; j++) printf("%10d", rand());
putchar('\n');
t += 10; // 10秒進める
}
}
実行結果
コード:
RAND_MAX = 32767
1541390473: 7494 14104 28540 5362 22556
1541390483: 7527 23285 10574 16619 27398
1541390493: 7560 32465 25376 27877 32240
1541390503: 7592 8877 7409 6366 4313
1541390513: 7625 18057 22211 17623 9155
1541390523: 7658 27237 4245 28880 13997
1541390533: 7690 3649 19046 7369 18839
1541390543: 7723 12829 1080 18626 23680
1541390553: 7756 22009 15882 29883 28522
1541390563: 7788 31189 30684 8373 596
次に getrand(-1, 100) の返す値ですが、それは、
-1 + (int) (rand() * 102 / (RAND_MAX + 1)) です。
「学習用c言語開発環境」は Visual C++ と同じで RAND_MAX が 32767
なので、rand() が返す値は 0~32367 です。
種の値がほとんど同じなので、最初の乱数は
7494~7788 と狭い範囲の値にしかなっていません。
102倍しても、764388~794376。(RAND_MAX + 1) は 32768。
この値で割ると、23.327~24.242。整数ですから、23~24。
これが、最初の乱数が同じ値になる理由です。
32768 は 2の 15乗ですから、32768 で割ることは、
15ビット右シフトするのと同じで、元の数の下位15ビットを
捨てることになっています。
乱数として、rand() % (max - min + 1) + min にしたほうが、
下位ビットの値を利用できて、もっと良くなると思います。
ただ、% による乱数の生成も問題があります。
32768 = 102 * 321 + 26 なので、rand() % 102 の結果、
0~25 の出る確率が 322/32768、26~101 の出る確率が 321/32768
となって一様ではないということです。
でも、乱数の最初の値は同じにはなりません。