有关rand(),srand()产生随机数学习总结
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
有关rand(),srand()产⽣随机数学习总结要计算机产⽣⼀个随机数不像扔⾊⼦⼀样,计算机的每⼀步操作,就是执⾏⼀堆代码,这些代码是事先安排好的,所以计算机的产⽣⾏
为是不具有随机性和预测性的(当然这⾥说的是现阶段的计算机体系,到未来的计算机的体系,未知),所以计算机产⽣的随机数都不是真正意义上的随机数,只是伪随机数,他以⼀个真值(也称为种⼦)作为初始条件,然后⽤⼀定的算法不停迭代产⽣随机数。
库函数中系统提供了两个函数⽤于产⽣随机数:srand()和rand();
rand函数:
头⽂件<stdlib.h>
定义函数:int rand(void),
函数功能:产⽣随机数,
函数说明:因为rand的内部是⽤线性同余法做的,不是真的随机数,只不过因为其周期特别长,所以在⼀定范围内可以看成是随机
的,rand()会返回⼀随机值,范围在0到RAND_MAX间,在调⽤此函数产⽣随机数前,必须利⽤srand()设好随机数种⼦,若没有设随机数种⼦,rand()在调⽤时会⾃动设随机数种⼦为1。
返回值:返回0到RAND_MAX之间的整数值,RAND_MAX的范围最少在32767之间(int),即双字节(16位)。
若unsigned int双字节是65535,且0-RAND_MAX每个数字被选中的随机率是相同的。
rand()产⽣的是假随机数,每次执⾏时是相同的,若要不同以不同的值来初始化,初始化的函数就是srand()。
srand函数:
头⽂件 <stdlib.h> ,
定义函数:void srand(unsigned int seed);
函数声明:srand()⽤来设置rand()产⽣随机数时的随机数种⼦,参数seed必须是整数,通常可以⽤time(0)的返回值作为seed.如果每次seed都设置相同的值,rand()产⽣的随机数值每次都⼀样。
srand(unsigned)time(NULL))使⽤系统定时/计数器的值作为随机种⼦每个种⼦对应⼀组根据算法预先⽣成的随机数,所以在相同平台的环境下,不同时间产⽣的随机数是不同的,相应的若将srand(unsigned)tima(NULL)改为任⼀常量,则⽆论何时运⾏,运⾏多少次得到的随机数都是⼀组特定的序列,所以srand⽣成的随机数是伪随机数。
但是,所谓的“伪随机数”指的并不是假的随机数,其实绝对的对技术只是⼀种假想状态的随机数,计算机只能⽣成相对的随机数,⽽这些随机数既是随机的⼜是有规律的,⼀部分遵守⼀定规律,⼀部分则不遵守任何规律,总结来说就是:计算机产⽣伪随机数⽽不是绝对的随机数(注:该内容来⾃:百度百科-rand函数)
在每次产⽣随机序列前,先指定不同的种⼦,这样计算出来的随机序列就不完全相同了,⽽使⽤同种⼦相同的数调⽤rand()会导致相同的随机数序列被⽣成。
例:
产⽣0到100之间的随机数:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
main()
{
int i,k;
srand( (unsigned)time( NULL ) );
for( i = 0; i < 10;i++ )
{
k=rand()%100+1; //rand()%100表⽰取100以内的随机数,即取了随机数后再对100取余 x=rand()%(Y-X+1)+X
printf( " k=%d\n", k );
}
}
由于rand产⽣的随机数是0到rand_max,⽽rand_max是⼀个很⼤的数,那么要产⽣⼀个从X到Y的随机数,可以这样:s=rand()%(x-
Y+1)+Y,这表⽰从X到Y范围内的随机数
系统在调⽤rand()之后就⾃动调⽤srand(),如果⽤户在rand()之前调⽤srand()给参数seed指定⼀个值,那么rand()就会将seed的值作为产⽣伪随机数的初始值,如果⽤户在rand()前没有调⽤srand(),系统会默认将1作为伪随机数的初始值,如果给了⼀个定值,每次rand()产⽣的随机数序列就⼀样了,所以为了避免发⽣上述情况,通常⽤srand((unsigned)time(0))或者srand((unsigned)time(NULL))来产⽣种⼦,如果觉得时间间隔太⼩,可以在(unsigned)time(0)或者(unsigned)time(NULL)后⾯乘以某个合适值,如srand((unsigned)time(NULL)*10)。
另外,还可以通过 j=(int)(n*rand()/RAND_MAX+1),⽤来产⽣0到N之间的整数:
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int main(void)
{
int i,j;
for(i=0;i<10;i++)
{
j=1+(int)(10*rand()/(RAND_MAX+1));
printf("%d ",j);
}
printf("\n");
return0;
}
产⽣随机数:
关于int x = rand() % n和 j=(int)(n*rand()/(RAND_MAX+1.0))的问题:
j=(int)(n*rand()/(RAND_MAX+1.0))就是随机⼀个0到n之间不包括n的浮点数,然后强制转换为就是0到9之间的整数了,这个跟x = rand() % n不同的地⽅就是,在多次随机出来的结果,前者理论更平均⼀些,后者只是和n求余得到的结果,没有前⾯的平均。
取模操作%是为了避免在某些情况下,某些伪随机数⽣成器产⽣的数,低位不够随机的问题,这⾥涉及到⼆进制问题,因为取模在⼆进制意义上可能代表取得低位。
不过在针对⾃⼰的需要下,随机数可以满⾜所需的情况下,int x = rand() % n是完全可以代替j=(int)(n*rand()/(RAND_MAX+1.0)),毕竟前者的时间性能要好。
rand函数是真正的随机数⽣成器,⽽srand()会设置提供rand()使⽤的随机数种⼦。
如果第⼀次调⽤rand()之前没有调⽤srand(),那么系统会为你⾃动调⽤srand()。
如下程序:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
main()
{
int i,k;
for( i = 0; i < 10;i++ )
{
k=rand()%100+1; //rand()%100表⽰取100以内的随机数,即取了随机数后再对100取余 x=rand()%(Y-X+1)+X
printf( " k=%d\n", k );
}
}
⼀样可以产⽣0到100间的随机数。
另外,srand这个函数要放到循环外⾯,或者循环调⽤的外⾯,否则调⽤得到的是相同的数字。
看下⾯例⼦:
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
main()
{
int i,j;
for(i=0;i<10;i++)
{
srand((int)time(0));
j=1+int(rand()*100.0/(RAND_MAX+1.0));
printf("%d ",j);
}
}
在执⾏结束后,会发现所有a[i]是⼀样的,srand放在循环⾥⾯,每产⽣⼀个随机数之前,都调⽤srand,由于计算机运⾏很快,这段代码总共执⾏不到1s,⽽srand()返回是以秒为单位,所以每次⽤time得到时间都是⼀样的,这相当于使⽤同⼀个种⼦产⽣产⽣随机序列,所以每次产⽣的随机数相同,于是出现所有a[i]是⼀样的,应该把srand放在循环外⾯。