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

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

#include  #include  #include  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%尾部。

我错过了什么吗? 谢谢!

您每次在外观周围使用相同的种子为伪随机数生成器播种。 只需将调用移到循环外的srand

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

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

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

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

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

试试这个版本:

 #include  #include  #include  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 

编辑 :Stratch我以前关于rand()评论 - 它不返回负值。

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

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

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

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

是啊。 这就是这一行:

 srand(time(NULL)); 

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

复制到srand(time(NULL))不会足够快地更改种子值 。 是的,如上所述,移动

 srand(time(NULL)); 

外面(之前;))循环:)

把srand放在外面循环。 调用srand(时间(null)只有一次。