有关rand(),srand()产生随机数学习总结
看到夏雪冬日的有关rand()和srand()产生随机数的总结,挺好的,学习了,然后又有百度其他人的成果,系统总结一下。本文转自夏雪冬日:http://www.cnblogs.com/heyonggang/archive/2012/12/12/2814271.html,Peng Lv:http://www.cnblogs.com/lvpengms/archive/2010/02/03/1663066.html#commentform。
要计算机产生一个随机数不像扔色子一样,计算机的每一步操作,就是执行一堆代码,这些代码是事先安排好的,所以计算机的产生行为是不具有随机性和预测性的(当然这里说的是现阶段的计算机体系,到未来的计算机的体系,未知),所以计算机产生的随机数都不是真正意义上的随机数,只是伪随机数,他以一个真值(也称为种子)作为初始条件,然后用一定的算法不停迭代产生随机数。
库函数中系统提供了两个函数用于产生随机数: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 = ; i < ;i++ )
{
k=rand()%+; //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=;i<;i++)
{
j=+(int)(*rand()/(RAND_MAX+));
printf("%d ",j);
}
printf("\n");
return ; }
产生随机数:
关于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 = ; i < ;i++ )
{
k=rand()%+; //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=;i<;i++)
{
srand((int)time());
j=+int(rand()*100.0/(RAND_MAX+1.0));
printf("%d ",j);
}
}
在执行结束后,会发现所有a[i]是一样的,srand放在循环里面,每产生一个随机数之前,都调用srand,由于计算机运行很快,这段代码总共执行不到1s,而srand()返回是以秒为单位,所以每次用time得到时间都是一样的,这相当于使用同一个种子产生产生随机序列,所以每次产生的随机数相同,于是出现所有a[i]是一样的,应该把srand放在循环外面。
如果计算伪随机数序列的初始值(种子)相同,那么计算出来的伪随机序列也完全相同,这个特性被有些软件加密解密,加密时,用某个种子生产一个伪随机数序列对数据进行处理;解密时,再利用种子数生产一个伪随机序列对加密数据进行还原。(详见:http://www.cnblogs.com/heyonggang/archive/2012/12/12/2814271.html)
有关rand(),srand()产生随机数学习总结的更多相关文章
- C++ Generate Rand Number Array by "srand()" 生成随机数
在C++中,我们有时想生成一个由随机数组成的数组,而且随机数的范围也可由我们来设定.那么我们就要用到srand()函数配合rand()来使用,参见如下代码: #include <vector&g ...
- C/C++中产生随机数(rand,srand用法)
计算机的随机数都是由伪随机数,即是由小M多项式序列生成的,其中产生每个小序列都有一个初始值,即随机种子.(注意: 小M多项式序列的周期是65535,即每次利用一个随机种子生成的随机数的周期是65535 ...
- C++随机数rand(), srand()
c++产生随机数会用到rand(), srand()函数,下面总结两个函数特性和使用. 1. rand() #include <iostream> #include <cstdlib ...
- C++用rand()和srand()生成随机数
内容来自<编程实战宝典> 首先来看函数原型 int rand(void); void srand(unsigned int seed); 1.rand()函数不需要任何参数,直接返回一个随 ...
- 数据结构及算法篇bsearch crypt lfind lsearch qsort rand srand
crypt(将密码或数据编码) 相关函数 getpass 表头文件 #define _XOPEN_SOURCE #include<unistd.h> 定义函数 char * crypt ( ...
- C++中用rand()和srand()产生随机数方法介绍
标准库<cstdlib>(被包含于<iostream>中)提供两个帮助生成伪随机数的函数: 函数一:int rand(void): 从srand (seed)中指定的see ...
- 随机数的生成 - rand(), srand()
2017-08-20 17:43:29 writer:pprp 我们采用随机数可以对我们的算法进行大数据检验 /* name : 简单的随机数生成算法 writer : pprp declare : ...
- 【转】随机函数 rand() srand() 以及seed的原理
from:http://blog.csdn.net/feige2008/article/details/6943885 标准库<cstdlib>(被包含于<iostream> ...
- rand srand
题外:先定义一个指针变量int *a; 再将整数b的地址赋给指针变量 a=&b ; 谨记指针变量a只是地址 *a相当于整数 之后*a 就可以表示 指向b了 也可以在定义的时候初始化 in ...
随机推荐
- PHP读取excel表格,和导出表格
读取表格 public function excel(){ import("Common.Vendor.Excel.PHPExcel"); $filename="./fi ...
- 树莓派安装OSMC打造家庭影院,还可以看优酷和CCTV
1.OSMC是什么? OSMC是树莓派官方推荐的影音系统,是一款开源的操作系统,是Openelec的升级版,同样是基于Kodi的开源项目.OSMC,使用它可以将树莓派打造成一款全功能的家庭影院系统,它 ...
- docker使用(一)
docker相对于虚拟技术: 更高效的利用系统资源 更快的启动速度 一致的运行环境 持续交付和部署 更加轻松的迁移 更加轻松的维护和扩展 什么是docker镜像,容器: 可以说他就是一个模型,用面向对 ...
- (数据科学学习手札51)用pymysql来操控MySQL数据库
一.简介 pymysql是Python中专门用来操控MySQL数据库的模块,通过pymysql,可以编写简短的脚本来方便快捷地操控MySQL数据库,本文就将针对pymysql的基本功能进行介绍: 二. ...
- 20155203 2016-2017-3 《Java程序设计》第4周学习总结
20155203 2016-2017-3 <Java程序设计>第4周学习总结 教材学习内容总结 1.父类和子类类似于集合和元素,不同的地方是子类可以拓展(extends)父类之外的方法. ...
- 20155215 《Java程序设计》实验一(Java开发环境的熟悉)实验报告
20155215 <Java程序设计>实验一(Java开发环境的熟悉)实验报告 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑 ...
- 20155317 2016-2017-2《Java程序设计》课程总结
20155317 2016-2017-2<Java程序设计>课程总结 每周作业链接汇总 新玮的首发博客:对师生关系的期望. C语言与java 20155317 王新玮第二次:语言掌握调查 ...
- 2017-2018-1 20155320加分项目——pwd的实现
2017-2018-1 20155320加分项目--pwd的实现 1 学习pwd命令 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 实现mypwd 4 测试mypwd ...
- BZOJ2039_employ人员雇佣_KEY
题目传送门 网络流,求最小割. 设tot为所有盈利的和,即所有人(不花钱)雇佣. 对于S->i建一条容量为c[i]的边,i->j建一条S[i][j]*2的边,之所以这样建是因为如果不选这个 ...
- day 4 继承
1.继承引入,减少代码量 1)版本1: class Animal: '''定义一个动物类''' def eat(self): print("----吃----") def drin ...