标准库rand()函数的缺陷以及Blitz++随机数生成的简介
rand函数原理

rand函数原理
rand函数是一种产生伪随机数的函数。
在计算机科学中,伪随机数指的是通过确定性算法产生的看似随机的数列。
rand函数的原理是根据一个种子值生成伪随机数,通过对种子值进行一系列的数学运算和变换,最终得到一个看似随机的数值。
然而,由于种子值是确定的,所以每次运行rand函数时,所得到的
数值序列是可以重现的。
通常情况下,rand函数会使用系统时钟作为种子值,以保证每次运行时得到的伪随机数序列都是不同的。
具体而言,rand函数会将种子值作为输入,然后通过一系列的算法和计算步骤,生成一个伪随机数作为输出。
这个输出的范围通常是0到RAND_MAX之间的一个整数。
而RAND_MAX的值则是由具体的编程语言或系统所定义的最大的随机数。
需要注意的是,rand函数所生成的伪随机数具有一定的重复性和周期性。
这是因为伪随机数的生成是基于种子值的计算,而如果种子值相同,那么所生成的伪随机数序列也会相同。
另外,伪随机数序列还存在一个周期,即在一定的循环次数后,所生成的伪随机数序列会重复。
因此,在使用rand函数时需要对
其生成的伪随机数进行适当的处理,以避免重复和周期性带来的问题。
有关rand(),srand()产生随机数学习总结

有关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⽣成的随机数是伪随机数。
C中的随机数

随机函数rand()(1)随机函数rand()产生一个0~RAND_MAX之间的整数,RAND_MAX是定义在头文件stdlib.h中的符号常量,因此在使用rand()时需要包含头文件stdlib.h,RAND_MAX的值是双字节整数的最大值32767。
#include "stdio.h"#include "stdlib.h"void main(){int i;for(i=1;i<=5;i++)printf("%d ",rand());}(2)利用rand()产生指定范围的随机数例:●rand()%b 产生[0,b-1]之间的数;●rand()%b+a 产生[a,a+b-1]之间的数;●rand()%(b-a+1)+a 产生[a,b]之间的数!!!rand()产生的随机数是伪随机数标准库函数srand()为使程序每次执行时产生不同的随机数序列(随机化),要调用标准库函数srand()为函数rand()设置随机种子。
#include "stdio.h"#include "stdlib.h"void main(){int i;unsigned seed;printf("Please enter seed: ");scanf("%u",&seed);srand(seed);for(i=1;i<=5;i++)printf("%d ",rand());}!!!如果每次输入随机数种子很麻烦,就可以让计算机自己产生一个随机数种子。
函数time()的使用函数time()定义在头文件time.h中,利用(unsigned)time(NULL)可以返回一个无符号整数,它是当前时间距标准时间的秒数。
#include "stdio.h"#include "stdlib.h"#include "time.h"void main(){int i;//unsigned seed;//printf("Please enter seed: ");//scanf("%u",&seed);srand((unsigned)time(NULL));for(i=1;i<=5;i++)printf("%d ",rand());}。
c语言rand函数的用法

c语言rand函数的用法在C语言中,rand()函数可以用来产生随机数,但是这不是真真意义上的随机数,是一个伪随机数,是根据一个数,我们可以称它为种子,为基准以某个递推公式推算出来的一系数,下面我们来看看c语言rand函数的用法。
rand(产生随机数)相关函数srand表头文件#include<stdlib.h>定义函数int rand(void)函数说明rand()会返回一随机数值,范围在0至RAND_MAX 间。
在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。
关于随机数种子请参考srand()。
返回值返回0至RAND_MAX之间的随机数值,RAND_MAX定义在stdlib.h,其值为2147483647。
范例/* 产生介于1 到10 间的随机数值,此范例未设随机数种子,完整的随机数产生请参考srand()*/#include<stdlib.h>main(){int i,j;for(i=0;i<10;i++){j=1+(int)(10.0*rand()/(RAND_MAX+1.0));printf("%d ",j);}}执行9 4 8 8 10 2 4 8 3 69 4 8 8 10 2 4 8 3 6srand(设置随机数种子)相关函数rand表头文件#include<stdlib.h>定义函数void srand (unsigned int seed);函数说明srand()用来设置rand()产生随机数时的随机数种子。
参数seed 必须是个整数,通常可以利用geypid()或time(0)的返回值来当做seed。
如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。
返回值范例/* 产生介于1 到10 间的随机数值,此范例与执行结果可与rand ()参照*/#include<time.h>#include<stdlib.h>main(){int i,j;srand((int)time(0));for(i=0;i<10;i++){j=1+(int)(10.0*rand()/(RAND_MAX+1.0)); printf(" %d ",j);}}执行5 8 8 8 10 2 10 8 9 92 9 7 4 103 2 10 8 7。
【C】揭秘rand()函数;

【C】揭秘rand()函数; 相信只要是程序猿都会知道rand()函数是⽤来取随机数的⼀个库函数,但是它出的结果真的是⼀组随机数吗?我们来看看这段代码运⾏的结果:1 #include<stdio.h>2 #include<stdlib.h>3int main(void)4 {5int j;6for(j=0;j<5;j++)7 {8 printf("rand():%d\n",rand());9 }10 }linux下gcc每次运⾏结果如下:windows vc6.0每次运⾏结果如下:(本⼈windows系统为64位机)(由于编译器的不同,可能显⽰的结果也不同吧!)rand()函数不是随机的吗?怎么每次运⾏的结果都是⼀样的?其实计算机也不像⼈们想象的那么智能,它也是按照⼈们的思想来随机出数的。
本⼈在linux下查找头⽂件没有找到rand()函数的定义,上⽹查了⼀下也没找到,说是被封装到库中了。
若是有⼤⽜们看到这篇⽂章,请帮帮⼩弟解决⼼中的疑问吧!那么如何⽤rand()函数获取你想要的取值范围呢?其实rand()函数的取值范围在0~RAND_MAX之间;那么什么是RAND_MAX呢?linux下的RAND_MAX值为2147483647(⼆进制32位)windows下的RAND_MAX值为32767(⼆进制16位)由此可见RAND_MAX是根据编译器对int型分配的空间⽽定的;这种说法应该也是错的,因为我在windows下的vc中打印sizeof(int)的值之后竟然显⽰4,也就是说int在vc中的存储空间应该是32位,所以我认为是vc编译器对rand()函数的定义做了修改,使RAND_MAX的值更⼩,⽅便了开发者的取值;(下⾯会介绍为什么编译器这样做)我们知道了rand()函数的取值范围后,如何取得你想要的数值范围呢?我们取0~10的值好了。
正常的思路如下,10*rand()/(RAND_MAX+1)+1(⽤10乘以rand()取得的随机数,然后除以RAND_MAX,再加1),应该是这样的了。
随机函数rand使用方法

随机函数rand使用方法随机函数rand使用方法随机函数rand是一种在编程中经常使用的函数,主要用于产生随机数。
随机数是指在一定范围内无法准确预测的数值。
程序中的随机数是由计算机随机生成的数值,可以用于模拟真实情况下的随机事件,如抽奖、掷骰子、随机化排序等。
在本文中,我们将介绍rand函数的使用方法,包括函数原型、函数作用、函数使用步骤、常见问题等内容,希望对使用随机函数rand的程序员有所帮助。
一、函数原型rand函数的原型如下:int rand(void);该函数没有参数,返回值为一个整数。
每次调用该函数,返回一个在0到RAND_MAX之间的随机整数。
RAND_MAX是一个宏定义,它表示随机整数的最大值。
例如,有些系统中的RAND_MAX值为32767,但也有一些系统中的RAND_MAX值为2147483647。
二、函数作用rand函数的作用是产生一个在0到RAND_MAX之间的随机整数。
程序员可以使用该函数生成随机数,并在程序中应用这些随机数进行适当的处理。
例如,一个抽奖程序可以使用随机函数生成抽奖的结果,每次抽奖结果都是不同的,可以增加游戏的趣味性。
在实际编程中,rand函数常用于以下几个方面:1. 生成随机数:程序员可以使用rand函数生成随机数,每次生成的结果都是不同的。
2. 模拟随机事件:程序员可以使用随机函数模拟随机事件的发生,如掷骰子、翻硬币等。
3. 随机化顺序:程序员可以使用随机函数将一个数组随机排序,达到打乱数组的目的。
三、函数使用步骤使用rand函数产生随机数,通常需要经过以下几个步骤:1. 引入头文件要使用rand函数,需要在程序中引入头文件stdlib.h,该头文件中包含了rand函数的函数原型。
2. 产生随机数种子rand函数生成随机数时需要一个随机数种子,用于计算随机数的产生。
程序员可以使用srand函数产生不同的随机数种子,从而获得不同的随机数序列。
如果没有使用srand函数初始化随机数种子,那么每次程序运行时,生成的随机数序列都是相同的。
c++rand函数

c++rand函数C++是一种广泛使用的编程语言,用于开发各种应用程序和系统软件。
C++中的rand函数是一个非常有用的函数,可以生成随机数字。
在这篇文章中,我们将介绍C++中的rand函数及其用法。
rand函数是C++中的一个库函数,用于生成伪随机数。
它的函数原型如下:int rand(void);该函数返回一个整数,这个整数的取值范围在0至RAND_MAX之间。
RAND_MAX是一个常量,它定义了可生成的最大随机数。
使用rand函数时,需要在程序中包含头文件cstdlib。
下面是一个简单的示例程序:#include <iostream>#include <cstdlib>using namespace std;int main(){int r = rand();cout << "随机数是:" << r << endl;return 0;}在上面的程序中,我们使用rand函数生成一个随机数,并将其打印到屏幕上。
注意,我们必须使用头文件cstdlib来包含rand函数。
rand函数不仅可以生成整数,也可以生成小数。
我们可以使用double类型来接收rand函数的返回值,然后进行转换。
下面是一个示例程序:#include <iostream>#include <cstdlib>#include <ctime>using namespace std;int main(){srand((unsigned) time(NULL));double r = (double)rand() / RAND_MAX;cout << "随机数是:" << r << endl;return 0;}在上面的程序中,我们使用了srand函数来为rand函数提供种子值。
rand函数 原理

rand函数原理
rand函数是一种在计算机编程中使用的随机数生成函数。
它基于某种算法或硬件设备产生随机数,以帮助程序员在需要随机性的情况下生成不可预测的数值。
rand函数的原理通常是基于伪随机数生成器(PRNG)算法。
PRNG是一种能够生成看似随机但实际上是通过确定性算法计算得出的随机数序列。
rand函数使用的PRNG算法主要有线性同余法、梅森旋转算法等。
在使用rand函数时,首先需要设置一个种子(seed)值。
种子值可以是一个固定值,也可以是基于时间或其他随机源生成的值。
种子值的作用是确定随机数序列的起始点。
随后,每次调用rand函数时,它都会根据当前种子值计算出一个伪随机数,并将种子值更新为下一个值。
这样,通过不断调用rand函数,可以生成一系列看似随机的数值。
需要注意的是,rand函数产生的随机数序列是有限的,并且在每次程序运行时都会有相同的种子值,因此可能会导致生成相同的随机数序列。
为了避免这种情况,可以在使用rand函数前使用srand函数设置一个不同的种子值。
总之,rand函数通过使用伪随机数生成算法,结合种子值的设置和更新,能够在编程中生成需要使用随机性的数值。
通过不断调用rand函数,可以获取一系列看似随机的数值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
标准库rand()函数的缺陷以及Blitz++随机数生成的简介(newsuppy,转载请注明出处)当我们需要在某个任务中使用随机数,通常我们习惯于使用标准库的rand函数。
像这样:srand(time(0)); //时间种子rand() % MAX_RAND;标准库的rand函数使用线性同余算法,是生成速度相当快的一种随机数生成算法。
在多数情况下也确实能满足我们的要求,但是对于一些特殊目的应用这个算法生成的随机数是不行的,比如某些加密算法,蒙特卡罗积分等(在.NET中创建随机密码的加密安全随机数就不能使用Random类的线性同余随机数,而要使用System.Security.Cryptography命名空间中的相关随机数生成类)。
这个线性同余算法的实现可以在很多书籍中找到。
下面我给出一个The C Programming Langurage 2nd中的一个实现,这也是普遍使用的标准库随机数算法的实现:unsigned long int next =1;/* rand: return pseudo-random integer on 0..32767 */int rand(void){next = next *1103515245+12345;return(unsigned int)(next/65536)%32768;}/* srand: set seed for rand() */void srand(unsignedint seed){next = seed;}这个实现的问题在于rand函数return行中的那个32768,在标准库中这个数字定义为RAND_MAX宏,在VisualC++和Mingw32编译器的stdlib.h头文件(或者cstdlib)中你都可以发现RAND_MAX的值为32768。
也就是说这个算法的随机数分布在0--RAND_MAX中,而在一般编译器中就是0--32768。
假设你的算法需要的是300000多个的随机数,那么使用rand函数会产生重负次数近30次的随机数!所以在这里我将简单介绍一下如何使用Blitz++库中的随机数生成类。
不过在这里我不能够证明Blitz++随机数算法相对于标准库有什么优越性。
Blitz++的源代码是开放的,你可以完全了解它的随机数算法的实现。
在Blitz++中随机数类组织在ranlib namespace中,使用方法也非常简单,seed成员函数种入种子后,再用random成员函数就可以了。
Blitz++中包括了产生各种概率分布情况的随机数,列举如下:均匀分布(Uniform),正态分布(Normal),指数分布(Exponential),Beta分布,Gamma分布,Χ方分布,F分布,离散均匀分布。
具体地可以参考Blitz++文档的第九章。
本文将会演示正态分布的随机数类。
NormalUnit<>()标准正态分布,μ= 0,σ= 1;Normal<>(T mean, T standardDeviation)正态分布,N(μ,σ^2),其中mean就是μ,standardDeviation就是σ。
Blitz++中随机数类的seed是共享的,调用一个类的seed后,其他类也同样种入了相同的种子。
对于种子的来源,Blitz++文档中有这样一个注意事项:Note: you may be tempted to seed the random number generator from a static initializer. Don't do it! Due to an oddity of C++, there is no guarantee on the order of static initialization when templates are involved. Hence, you may seed the RNG before its constructor is invoked, in which case your program will crash. If you don't know what a static initializer is, don't worry -- you're safe!(幸运的是我也不太清楚static initializer具体指什么,:-))1,先来看一个标准正态分布的例子,根据3σ法则(正态分布的随机数几乎全部落在(μ-3σ,μ+3σ)中),这些随机数应该大部分落在(-3, 3)之间。
下面的程序产生10000个正态分布随机数,然后导入Matlab生成图形,横坐标是随机数的序数,纵坐标是随机数值。
很显然,大部分点在3σ区间内。
在区间(μ-σ,μ+σ)中数据点最密。
#include<random/uniform.h>#include<random/normal.h>#include<iostream>#include<fstream>#include<ctime>#include<cstdlib>using namespace std;using namespace ranlib;int main(){const size_t MAXGEN =10000;NormalUnit<float> rnd;rnd.seed(time(0));ofstream file("c:\\file.txt");// generator Normal distribution random numberfor(size_t i=0; i<MAXGEN;++i){file << rnd.random()<<" ";}}2,下面是一个服从于μ= 10,σ= 2的正态分布,根据3σ法则,大部分点应该落在(4,16)之间。
#include<random/uniform.h>#include<random/normal.h>#include<iostream>#include<fstream>#include<ctime>#include<cstdlib>using namespace std;using namespace ranlib;int main(){const size_t MAXGEN =1000000;const int mu =10;const int sigma =2;Normal<float> rnd(mu,sigma);rnd.seed(time(0));ofstream file("c:\\file.txt");// generator Normal distribution random number for(size_t i=0; i<MAXGEN;++i){file << rnd.random()<<" ";}}3,生成前述正态分布的钟型曲线(PDF)。
这里产生1M的float随机数,然后乘以10转型为整数,统计在区间0-170之间随机数出现的概率,这样再导入Matlab生成图形就是一个近似的正态分布的钟型曲线了。
#include<random/uniform.h>#include<random/normal.h>#include<iostream>#include<fstream>#include<ctime>#include<cstdlib>using namespace std;using namespace ranlib;int main(){const size_t MAXGEN =1000000;const int mu =10;const int sigma =2;Normal<float> rnd(mu,sigma);rnd.seed(time(0));ofstream file("c:\\file.txt");float*rndArray =newfloat[MAXGEN];// generator Normal distribution random numberfor(size_t i=0; i<MAXGEN;++i){rndArray[i]= rnd.random();}int*rndConvertIntArray =newint[MAXGEN];int multiple =10;// convert float random number to integerfor(size_t i=0; i<MAXGEN;++i){rndConvertIntArray[i]=int(rndArray[i]* multiple);}const size_t PDFSIZE =(mu +3* sigma)* multiple;const size_t redundancy =10;int*pdf =newint[PDFSIZE+redundancy];for(size_t i=0; i<PDFSIZE+redundancy;++i){pdf[i]=0;}// generator PDF(Probability Distribution Function), Normal distribution is a "bell" shape for(size_t i=0; i<MAXGEN;++i){if(rndConvertIntArray[i]<= PDFSIZE+redundancy-1){++pdf[rndConvertIntArray[i]];}}for(size_t i=0; i<PDFSIZE+redundancy;++i){file << pdf[i]<<" ";}delete[] rndArray;delete[] rndConvertIntArray;delete[] pdf;}钟型曲线,当然不是特别光滑( ), 大部分随机数都出现在( 4 ,16 )区间内。
总结,Blitz++ 的随机数生成类应该说是值得信任的。
[ 参考文献]1,概率论与数理统计(3rd),浙江大学盛骤谢式千潘承毅编高等教育出版社2,C 数值算法(2nd),[ 美] William H. Press, Saul A. Teukolsky, William T. Vetterling,Brian P. Flannery著傅祖芸赵梅娜丁岩石等译,傅祖芸审校3 ,Matlab 6.5 的文档The MathWorks, Inc.。