调用rand()返回非随机结果

时间:2012-03-13 14:40:59

标签: c

我正在编写一个简单的C程序,它将硬币投掷100000次并计算使用srand和rand投掷多少个头和多少尾巴。这就是我所拥有的:

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

int main(void){

    int i;
    int h=0;
    int t=0;
    int n;

    for(i=0;i<100000;i++){
        srand(time(NULL));
        n=rand()%2;
        if(n==0){
            h++;
        }
        else {   
            t++;
        }
    }

    printf("%d heads\n", h);
    printf("%d tails\n", t);

    return EXIT_SUCCESS;
}

然而,在运行程序时,我有时会得到100000个头和0个尾部,有时会有0个头和100000个尾部,有时我会在头部和尾部得到随机数,但不会有50%的头部50%尾部。

我错过了什么吗? 谢谢!

8 个答案:

答案 0 :(得分:7)

每次在外观周围使用相同的种子播种伪随机数生成器。只需将呼叫移至循环外的srand即可。

srand(time(NULL));
for(i=0;i<100000;i++){
    n=rand()%2;
    .....

pseudo-random number generator(PRNG)是确定性的。也就是说,给定相同的初始种子,每次调用时它将返回相同的数字序列。在您的代码中,由于每次调用rand时都会播种,因此在循环的每次迭代中都会获得相同的1个数字序列。现在,程序的不同执行会产生不同的结果,因为time会发生变化。

在你没有看到100%头部或100%尾部的情况下,那就是当循环花费足够长的时间来推进时。

答案 1 :(得分:2)

是的,如果你正在使用srand,它会使用时间随机获取一个数字,所以如果你或计算机在不到一秒的时间内随机选择一个值,那么每次都会得到相同的数字。

答案 2 :(得分:1)

我认为问题是每次迭代都会调用srand();你只需要打电话一次。

试试这个版本:

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

int main(void){


int i;
int h=0;
int t=0;
int n;

srand(time(NULL));
for(i=0;i<100000;i++){
    if((rand() & 1) == 1){
        h++;
    }
    else{
        t++;
    }
}

printf("%d heads\n", h);
printf("%d tails\n", t);

return EXIT_SUCCESS;
}

这给出了相当一致的结果:

$ ./rand
49980 heads
50020 tails
$ ./rand
50131 heads
49869 tails
$ ./rand
50000 heads
50000 tails
$ ./rand
50000 heads
50000 tails
$ ./rand
50093 heads
49907 tails
$ ./rand
50093 heads
49907 tails

编辑:抓住我之前关于rand()的评论 - 它不会返回负值。

答案 3 :(得分:0)

请勿在循环中调用srand。如果你要调用它,它应该在执行的最开始只被调用一次。

实际上,你在每次使用它之前将随机数发生器重置为相同的种子(除非第二个边界经过)...所以当它得到一致的结果时应该不足为奇! / p>

答案 4 :(得分:0)

你在循环的每次迭代中使用相同的种子值。

srand(time(NULL));移至for循环之前。

答案 5 :(得分:0)

呀。这就是这一行:

srand(time(NULL));

for循环之前移动它,它将正常工作。 srand设置种子,所以如果你这样称呼time(NULL)不会改变(并且很可能),rand()将始终返回相同的值。

答案 6 :(得分:0)

复制到srand(time(NULL)) doesn't change seed value quick enough。 是的,如上所述,移动

srand(time(NULL)); 

外(前;))循环:)

答案 7 :(得分:0)

将srand放在外面循环。只调用一次srand(time(null)。