随机数的N种生成方式首先需要说明的是,计算机中生成的随机数严格来说是伪随机的,即不是真正的随机数,真正随机数的随机样本不能再现。那么让我们看一下代码中可以生成随机数的方式。randrand函数声明如下:#includeintrand(void);rand函数返回[0,RAND_MAX)范围内的随机整数。在我的机器上,RAND_MAX是2147483647。用法示例:rand.c*/#include#includeintmain(void){inti=0;while(i<5){printf("%d",兰德());i++;}printf("\n");return0;}编译运行:$gcc-orandrand.c./rand1804289383846930886168169277717146369151957747793多运行几次,你会惊喜的发现每次运行的结果都是一样的!!!这还是在玩yarn?srand不用担心,虽然rand每次的结果都是一样的,但这是因为它的种子默认为1。每颗种子都会有一串看似随机的序列,每取出一颗,整体分布几乎是随机的。但如果你的种子每次都是一样的,那么每次运行很可能会得到相同的结果。我们需要用srand播种它。#includevoidsrand(unsignedintseed);为了保证我们每次得到的随机数都不一样,我们必须保证每次调用的种子都不一样,所以我们通常选择使用时间作为种子,注意这个只是平时的种子选择,大家可以根据自己的实际需要来选择。所以我们在使用它之前设置种子。例子:rand.c*/#include#include#includeintmain(void){srand(time(NULL));//设置随机种子,注意你只需要设置一次inti=0;while(i<5)//生成5个随机数{printf("%d",rand());i++;}printf("\n");return0;}现在好了,每次运行都不一样。但是还有一个问题。如果在多线程下使用这种方法,是不可取的,因为rand不是可重入函数。每次调用它都会修改一些隐藏的属性,所以不适合在多线程中使用。为了在多线程下使用rand_r,我们和rand一样使用rand_r:#includeintrand_r(unsignedint*seedp);使用示例:#include#include#includeintmain(void){unsignedintseed=time(NULL);inti=0;while(i<5)//生成5个随机数{printf("%d",rand_r(&seed));i++;}printf("\n");return0;}在多线程中,多个线程可能几乎同时被调用,所以它们的种子可能是一样的。如果想要不一样,也可以设置seed与threadid相关。unsignedintseed=time(NULL)^pthread_self();random从前面的例子我们可以发现,rand生成的整数范围是有限的。为了生成更大的范围,可以使用random:#includelongintrandom(void);voidsrandom(unsignedintseed);随机返回longint类型,因此在某种程度上它会生成更大的范围。另外,和rand类似,需要使用srandom函数设置种子。具体例子不会公布。生成指定范围内的随机数前面的例子都是生成[1,RAND_MAX]之间的数。如果你想在指定的时间间隔内生成随机数怎么办?假设a和b不超过int的范围,它们的差不超过rand的范围。[a,b)左闭右开区间,包括a,不包括:(rand()%(b-a))+a;[a,b]左闭右闭区间,包括a和b:(rand()%(b-a+1))+a;(a,b]左开右闭,即不包含a,但包含b:(rand()%(b-a))+a+1;[0,b]rand()%b;0到1之间的浮点数rand()/(double)RAND_MAX;例如在[2,10]之间生成5个随机数:#include#include#includeintmain(void){srand(time(NULL));//设置随机种子,注意只需要设置一次inti=0;inta=2;intb=10;while(i<5)//生成5个随机数{printf("%d",(rand()%(b-a))+a);i++;}printf("\n");return0;}总结记住,通过这些方法生成伪随机数。好的随机算法具有很强的随机性,可能需要根据使用场景设计特定的算法。本文介绍的只是库函数提供的随机数生成函数。