|
> rand()の戻り値は[0, RAND_MAX]の範囲の値ですから,((double)RAND_MAX)で割る事によって,[0, 1]の範囲の乱数を得る事が出来ます。
> あとは20倍して10を引けば,目的の[-10, 10]の範囲の乱数を得る事が出来ます。
その方法(下記A)では +10 の発生確率に問題があります。
C FAQに載っている方法(下記C-FAQ1,2,3)と合わせて特性を比較してみました。
C FAQ 13.16:
http://www.kouno.jp/home/c_faq/c13.html#16
[test.c]
#include <stdio.h>
#define RAND_MAX 32767
int main(void)
{
long areaA[21] = {0};
long area1[21] = {0};
long area2[21] = {0};
long area3[21] = {0};
long *countA = areaA + 10;
long *count1 = area1 + 10;
long *count2 = area2 + 10;
long *count3 = area3 + 10;
int rand;
int n;
for (rand = 0; (unsigned)rand <= RAND_MAX; rand++) {
n = (int)(rand / (double)RAND_MAX * 20) - 10; /* A */
countA[n]++;
n = rand % 21 - 10; /* C-FAQ1 */
count1[n]++;
n = (int)(rand / (RAND_MAX + 1.0) * 21) - 10; /* C-FAQ2 */
count2[n]++;
n = rand / (RAND_MAX / 21 + 1) - 10; /* C-FAQ3 */
count3[n]++;
}
printf("\tA\tC-FAQ1\tC-FAQ2\tC-FAQ3\n");
for (n = -10; n <= +10; n++) {
printf("%+d\t%ld\t%ld\t%ld\t%ld\n", n, countA[n], count1[n], count2[n], count3[n]);
}
return 0;
}
[実行結果]
>lcc test
>test
A C-FAQ1 C-FAQ2 C-FAQ3
-10 1639 1561 1561 1561
-9 1638 1561 1560 1561
-8 1639 1561 1561 1561
-7 1638 1561 1560 1561
-6 1638 1561 1560 1561
-5 1639 1561 1561 1561
-4 1638 1561 1560 1561
-3 1638 1561 1561 1561
-2 1639 1560 1560 1561
-1 1638 1560 1560 1561
+0 1638 1560 1561 1561
+1 1639 1560 1560 1561
+2 1638 1560 1560 1561
+3 1638 1560 1561 1561
+4 1639 1560 1560 1561
+5 1638 1560 1561 1561
+6 1638 1560 1560 1561
+7 1639 1560 1560 1561
+8 1638 1560 1561 1561
+9 1638 1560 1560 1561
+10 1 1560 1560 1548
>
|