版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、本文档如对你有帮助,请帮忙下载支持!1. 基本函数在C语言中取随机数所需要的函数是 :int rand(void);void srand(unsignedint n);rand()函数和srand()函数被声明在头文件 stdlib.h中,所以要使用这两个函数必须包含该头文件:#inelude 2. 使用方法rand()函数返回0至U RAND_MAX 之间的伪随机数(pseudorandom) 。RAND_MAX 常量被定义在 stdlib.h 头文件中。其值等于32767,或者更大。srand()函数使用自变量n作为种子,用来初始化随机数产生器。只要把相同的种子传入 srand(),然后调
2、用rand()时,就会产生相同的随机数序列。因此,我们可以把时间作为srand()函数的种子,就可以避免重复的发生。如果,调用rand()之前没有先调用srand(),就和事先调用srand(1)所产生的结果一 样。/*例1 :不指定种子的值*/for (int i=0; i10; i+)printf(%d , rand()%10);每次运行都将输出:1 7 4 0 9 4 8 8 2 4/*例2:指定种子的值为1 */sran c(1);for (int i=0; i10; i+)printf(%d , rand()%10);每次运行都将输出:1 7 4 0 9 4 8 8 2 4 例2的输
3、岀结果与例1是完全一样的。/*例3:指定种子的值为8 */sran c(8);for (int i=0; i10; i+)printf(%d , rand()%10);每次运行都将输出:4 0 1 3 5 3 7 7 1 5该程序取得的随机值也是在0,10 )之间,与srand(1)所取得的值不同,但是每次运行程序的结果都相 同。/*例4:指定种子值为现在的时间*/sranc(unsignec)time(NULL);for (int i=0; i10; i+)printf(%d , rand()%10);该程序每次运行结果都不一样,因为每次启动程序的时间都不同。另外需要注意的是,使用time(
4、)函数前必须包含头文件time.h 。3. 注意事项求一定范围内的随机数。如要取0,10)之间的随机整数,需将 rand()的返回值与10求模。randnumber= rand() % 10;那么,如果取的值不是从 0开始呢?你只需要记住一个通用的公式。要取a,b)之间的随机整数(包括 a,但不包括b),使用:(rand() % (b - a) + a伪随机浮点数。要取得01之间的浮点数,可以用:rand() / (double)(RAND_MAX)如果想取更大范围的随机浮点数,比如0100,可以采用如下方法:rand() /(double)(RAND_MAX)/100)其他情况,以此类推,这
5、里不作详细说明。当然,本文取伪随机浮点数的方法只是用来说明函数的使用办法,你可以采用更好的方法来实现。举个例子,假设我们要取得010之间的随机整数(不含 10本身):大家可能很多次讨论过随机数在计算机中怎样产生的问题,在这篇文章中,我会对这个问题进行更深入的 探讨,阐述我对这个问题的理解。首先需要声明的是,计算机不会产生绝对随机的随机数,计算机只能产生伪随机数”。其实绝对随机的随机数只是一种理想的随机数,即使计算机怎样发展,它也不会产生一串绝对随机的随机数。计算机只 能生成相对的随机数,即伪随机数。伪随机数并不是假随机数,这里的伪”是有规律的意思,就是计算机产生的伪随机数既是随机的又是有规律的
6、。怎样理解呢?产生的伪随机数有时遵守一定的规律,有时不遵守任何规律;伪随机数有一部分遵守一定的规律;另一部分不遵守任何规律。比如世上没有两片形状完全相同的树叶 ”,这正是点到了事物的特性,即随机性,但是每种树的叶子都有近似的形状,这正是事物的共性,即规律性。从这个角度讲, 你大概就会接受这样的事实了:计算机只能产生伪随机数而不能产生绝对随机的随机数。那么计算机中随机数是怎样产生的呢?有人可能会说,随机数是由随机种子”产生的。没错,随机种子是用来产生随机数的一个数,在计算机中,这样的一个 随机种子”是一个无符号整形数。那么随机种子 是从哪里获得的呢?下面看这样一个C程序:/ran dOl.c#i
7、n cludestatic un sig nedi nt RAND_SEED;un sig nedi nt ran dom(void)RAND_SEED =(RAND_SEED * 123+59)%65536;return( RAND_SEED);void ran dom_stari(void)int temp2;movedata(0x0040,0x006c,FP_SEGtemp),FP_OFF(temp),4);RAND_SEED=temp0;mai n()un sig nedi nt i,n; ran dom_star(); for(i=0;i10;i+) prin tf (%ut ,ra
8、n dom();prin tf(n);这个程序(randOl.c )完整地阐述了随机数产生的过程:首先,主程序调用random_start() 方法,random_start()方法中的这一句我很感兴趣:movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);这个函数用来移动内存数据,其中FP_SEG (far pointer to segment)是取temp数组段地址的函数,FP_OFF ( far pointer to offset )是取temp 数组相对地址的函数,movedata 函数的作用是把位于0040:006CH存储单元中的双字
9、放到数组 temp的声明的两个存储单元中。这样可以通过 temp数组把0040:006CH 处的一个16位的数送给 RAND_SEED。random 用来根据随机种子RAND_SEED 的值计算得出随机数,其中这一句:RAND_SEED = (RAND_SEED*123+59)%65536;是用来计算随机数的方法,随机数的计算方法在不同的计算机中是不同的,即使在相同的计算机中安 装的不同的操作系统中也是不同的。我在linux和windows 下分别试过,相同的随机种子在这两种操作系统中生成的随机数是不同的,这说明它们的计算方法不同。现在,我们明白随机种子是从哪儿获得的,而且知道随机数是怎样通过
10、随机种子计算岀来的了。那么,随机种子为什么要在内存的 0040:006CH 处取? 0040:006CH处存放的是什么?学过计算机组成原理与接口技术这门课的人可能会记得在编制ROM BIOS时钟中断服务程序时会用到Intel 8253 定时/计数器,它与Intel 8259中断芯片的通信使得中断服务程序得以运转,主板每秒产生的18.2次中断正是处理器根据定时/记数器值控制中断芯片产生的。在我们计算机的主机板上都会 有这样一个定时/记数器用来计算当前系统时间,每过一个时钟信号周期都会使记数器加一,而这个记数器的值存放在哪儿呢?没错,就在内存的0040:006CH处,其实这一段内存空间是这样定义的
11、:TIMER_LOW DW ?;地址为 0040:006CHTIMER_HIGH DW ?;地址为 0040:006EHTIMER_OFT DB ?;地址为 0040:0070H时钟中断服务程序中,每当TIMER_LOW 转满时,此时,记数器也会转满,记数器的值归零,即TIMER_LOW 处的16位二进制归零,而 TIMER_HIGH 加一。rand01.c 中的 movedata(0x0040,0x006c,FP_SEG(temp),FP_0FF(temp),4);正是把TIMER_LOW 和TIMER_HIGH 两个16位二进制数放进 temp 数组,再送往RAND_SEED , 从而获得
12、了随机种子”。现在,可以确定的一点是,随机种子来自系统时钟,确切地说,是来自计算机主板上的定时/计数器在内存中的记数值。这样,我们总结一下前面的分析,并讨论一下这些结论在程序中的应用:1. 随机数是由随机种子根据一定的计算方法计算岀来的数值。所以,只要计算方法一定,随机种子一 定,那么产生的随机数就不会变。看下面这个C+程序:/ran d02.cpp#include #include using n amespacestd;int main()un sig nedi nt seed= 5;sran dfseed;un sig nedi nt r = ran d();cout r endl;在相
13、同的平台环境下,编译生成 exe后,每次运行它,显示的随机数都是一样的。这是因为在相同的 编译平台环境下,由随机种子生成随机数的计算方法都是一样的,再加上随机种子一样,所以产生的随机 数就是一样的。2. 只要用户或第三方不设置随机种子,那么在默认情况下随机种子来自系统时钟(即定时/计数器的值)看下面这个C+程序:/ran d03.cpp#include #include using n amespacestd;int main()sranc(unsigned)time(NULL);un sig nedi nt r = ran d();cout r endl;return 0;这里用户和其他程序
14、没有设定随机种子,则使用系统定时/计数器的值做为随机种子,所以,在相同的平台环境下,编译生成 exe后,每次运行它,显示的随机数会是伪随机数,即每次运行显示的结果会有不 同。3. 建议:如果想在一个程序中生成随机数序列,需要至多在生成随机数之前设置一次随机种子。看下面这个用来生成一个随机字符串的C+程序:/ran d04.cpp#in clude#in cludeusing namespacestd;int mai n()in t rNum,m = 20;char*ch = new charm;for (int i = 0; i m; i+ )大家看到了,随机种子会随着for循环在程序中设置多
15、次sranc(unsigned)time(NULL )*j);/j 是后加的外层循环rNum = 1+(int)(rand()/(double)RAND_MAX )*36); 求随机值switch (rNum)easel: chi=a;break;case2: chi=b;break;case3: chi=c;break;case4: chi=d;break;case5: chi=e;break;case6: chi=f;break;case7: chi=g: break;case8: chi=h; break;case9: chi=i; break;case10: chi=j; break;
16、casell: chi=k;break;case12: chi=T; break;case13: chi=m; break;case14: chi= n: break;case15: chi=o; break;case16: chi=p;break;case17: chi=q; break;case18: chi=r; break;case19: chi=s; break;case20: chi=t; break;case21: chi=u:break;case22: chi=v;break;case23: chi=w;break;case24: chi=x;break;case25: chi
17、=y;break;case26: chi=z;break;case27:chi=O;break;case28:chi=1;break;case29:chi=2;break;case30:chi=3;break;case31:chi=4;break;case32:chi=5;break;case33:chi=6;break;case34:chi=7;break;case35:chi=8;break;case36:chi=9;break;/e nd of switchcout chi; /end of for loopcout endl;delete ch;return 0;而运行结果显示的随机字
18、符串的每一个字符都是一样的,也就是说生成的字符序列不随机,所以我们需要把srand(unsigned)time(NULL);从for循环中移出放在for语句前面,这样可以生成随机的字符序列,而且每次运行生成的字符序列会不同(呵呵,也有可能相同,不过出现这种情况的几率太小了)。如果你把srand(unsigned)time(NULL);改成srand(2); 这样虽然在一次运行中产生的字符序列是随机的,但是每次运行时产生的随机字符序列串是相同的。把srand这一句从程序中去掉也是这样。此外,你可能会遇到这种情况,在使用timer控件编制程序的时候会发现用相同的时间间隔生成的一组随机数会显得有规律,而由用户按键command 事件产生的一组随机数却显得比较随机,为什么?根据我们上面的分析,你可以很快想岀答案。 这是因为timer是由计算机时钟记数器精确控制时间间隔的控件, 时间间隔相同,记数器前后的值之差相同,这样时钟取值就是呈线性规律的,所以随机种子是呈线性规律 的,生成的随机数也是有规律的。而用户按键事件产生随机数确实更呈现随机性,因
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025解除合同公函示范文
- 刀口愈合护理方法
- 贫血常见症状及护理指导手册
- 2025版急性肾小管坏死诊疗与护理指南
- 保安消防安全培训
- 2025版子宫内膜异位症症状解析及护理计划
- 2025年上海安全知识竞赛考试复习题库及答案
- 2025版产前诊断与遗传咨询知识检测答案及解析
- 幼儿科普紫荆花
- 房地产门店介绍
- 名师工作室成员工作总结
- 饮料销售知识培训课件
- 2025年贵州省遵义市中小学生“π”节数学思维竞赛初赛ZYMC2数学试卷(六年级)(含解析)
- 2025年下半年四川省泸州市人力资源和社会保障局信息中心招聘3人重点基础提升(共500题)附带答案详解
- 佛山地库信号覆盖施工方案
- 2025年国家开放大学(电大)《应用写作》期末考试备考试题及答案解析
- 学堂在线 高技术与现代局部战争 章节测试答案
- 新版苏教版四年级上册科学(全册教案及教学计划及进度表)
- 蓝豚医陪陪诊服务发展研究报告2025
- 国际压力性损伤-溃疡预防和治疗临床指南(2025年版)解读课件
- 住培教学病例讨论规范
评论
0/150
提交评论