您的位置:首页 > 其它

随机数的产生

2014-07-31 00:30 176 查看
之前总是搞不清楚rand 、srand  的关系,也不明白随机数与种子的关系,拖了这么久,现在就认真看一看吧 !

------如何得到1到99的随机数,请看末尾。。。。

#include <stdlib.h>

在调用此rand函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为 1 。这样每次执行起来得到的一组由rand产生的随机数就失去了随机性。关于随机数种子请参考srand()。

首先我们要注意到,rand虽然是最终产生随机数的函数,但它的原型是int rand(void),也就是我们每次调用都只能是用rand()的形式,既然每次都是用同样的形式去调用,那么根据rand()的实现方式——根据系统里保存的某个值(种子)来进行一系列算术运算得到的值,rand()只是做到去取这个值然后计算,并且将计算的中间值再重新赋予系统中的值,若在调用rand()之前没有去赋予系统的这个值(种种子)的话,那么rand()会默认这个种子为1(赋为1),那么程序运行起来后得到第一个随机值又是和前一次执行时得到的第一个随机值是一样的了,因为它们的种子都为1!尽管每调用一次rand(),会去改变下种子的值(系统中存储的那个值),但是没用,因为在没种子前调用rand(),rand
会每次都将种子初始化为1,而rand()的计算方式也不变,那么就导致rand能实现的随机是在程序一次执行时的随机,而程序的执行与执行之间是做不到随机的,得到的都是相同的一组随机数,知道了一次执行得到的那组随机数,那么在另一个程序执行前我们就能根据rand()在这个程序里调用的次数推算出它得到的随机值。所以单单用rand()来执行的话,那么每次程序一运行起来第一次调用rand()得到的随机数值都是相同的,因为种子又被rand初始化成1了,每次程序刚运行起来这个值也就是始终没变的,而计算推理方式又不变,那么自然一次运行里得到的“随机数”也就只能是做到相对随机,而不是真正的随机。所以说若想要达到随机的目的,最关键在于要在程序刚运行起来后与第一次调用rand()之前就要改变系统中的存储的那个值。而rand()的实现里压根就没去动这个初始值,只是读取这个值而已,所以我们又需要用另一个函数去改变这个值来辅助rand()从而实现随机数的功能,而这个函数我们称为srand(int)函数,srand(int)完成的唯一操作就是用它的int参数去赋值系统中的那个值,我们称这个参数为种子,srand(int)的函数原型为 void
srand (unsigned int seed);我们也可以称srand函数为种子函数。因为种子函数完成的是系统内部值的赋值关系。所以它的种子参数就很重要了,因为是直接赋予,而rand()的实现方式固定,所以设置相同的种子参数,rand()得到的随机数也是固定的。所以最重要的是要保证srand设置的种子不能够相同,这样又rand()推理出来的随机数才能够有很好的随机效果。所以我们常常用系统时间time(0)来作为种子,因为每一时刻的系统时间都是不一样的,这样子让能做到每次执行得到的一组随机数都是和之前不同的。

我们先看看srand、rand 这两个函数的原型好了:

void srand (unsigned int seed);                   
                                                                            

srand()用来设置rand()产生随机数时的随机数种子。参数seed必须是个整数,通常可以利用geypid()或time(0)的返回值来当做seed。如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。  

int rand(void)                                                                                                 
      


rand()会返回一随机数值,范围在0至RAND_MAX 间。在调用此rand函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为 1 。这样每次执行起来得到的一组由rand产生的随机数就失去了随机性。关于随机数种子请参考srand()。 
 

rand的返回值是在[0, RAND_MAX]之间的数据,RAND_MAX在不同的系统中数值有所不同。 
                                                                                              

根据上面所说,我们先来看看rand()是怎么实现的好了:

static unsigned long next = 1;

/* RAND_MAX assumed to be 32767 */

int rand(void) 

{

next = next * 1103515245 + 12345;

return((unsigned)(next/65536) % 32768);

}

voidsrand(unsigned seed) {

next = seed;

}

在看看如何应用srand()和rand()来得到自己想要的范围内的随机数:

---------------------------------------单独用rand的效果------------------------------------------------------------

/* 单独使用rand()产生介于1 到10 间的随机数值,此范例未设随机数种子*/

int main(void)

{
int i,j;
for(i=0;i<10;i++)
{
j=1+(int)(10.0*rand()/(RAND_MAX+1.0));
printf("%d ",j);
}
return 0;

}

/*

重复执行两次,得到的结果都是相同的

第一次执行: 9 4 8 8 10 2 4 8 3 6 

第二次执行: 9 4 8 8 10 2 4 8 3 6 

*/

----------------------------------------srand和rand联用的效果--------------------------------------------------------

/*用srand(int) 和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);
}

}

/*

重复执行所得的组结果都是不同的:

2 1 5 4 7 2 3 2 5 4 

9 9 1 5 10 6 5 3 6 5 

10 6 5 10 8 8 6 2 6 8

*/

===================================================================================================================
//而如果每次给系统种下的种子都相同,则得到的随机数也是相同的:

int main()

{

    int i;

    for (i = 0; i < 6; i++)

    {

        srand(1);

        printf("%d ", rand());

    }

    return 0;
}

//得到的随机值都相同:1804289383 1804289383 1804289383 1804289383 1804289383 1804289383

如何写出每次运行结果都不同的随机序列呢?我们来看下例:
int main()  
{  
    int i;  
    srand(time(NULL));  //只要起初出现一次就好了
    for (i = 0; i < 6; i++)  
    {  
        printf("%d ", rand());  
    }  
    getchar();  
    return 0;  
}  
/*
得到的每个随机数都不同,甚至是不同执行下得到的一组随机数也不同:
578483064 1540932591 1356376671 2008620233 1138309963 303713139
410218365 1405552895 904029937 315746375 583604631 922918102 
*/================================================================================================================

//分别产生0 到99、1 到99 、10 到19、10 到20的随机数各10 个并输出

int main()

{
int rand_num,i =10;
srand( (int)time(0) );
while(i--)// 0 到99
printf("%d\t",rand()%99);//要产生0 到n 的随机数,则rand()%(n+1)
printf("\n");

i =10;
while(i--)// 1 到99
printf("%d\t",rand()%99+1);//要产生1 到n 的随机数,则rand()%n+1
printf("\n");

i =10;
while(i--)// 10 到19
printf("%d\t",rand()%(20-10)+10);//要产生m 到n 的随机数,则rand()%(n-m)+m 得到的是m 到n-1 的,而rand()%(n+1-m)+m才是m 到n 的
printf("\n");

i =10;
while(i--)//10 到20
printf("%d\t",rand()%(20+1-10)+10);//要产生m 到n 的随机数,则rand()%(n-m)+m 得到的是m 到n-1 的,而rand()%(n+1-m)+m才是m 到n 的
printf("\n");

return 0;

}

/*尽量多执行几次找些具有代表性的结果出来:

98 81 59
34 70
81 81 0
27 67

99 2 16
2 4
37 58 98
82 1

19 14 15
10 10
10 15 10
18 13

20 10 15
11 16
14 19 15
15 18

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: