调用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)只有一次。