【C】揭秘rand()函数;
原文地址:http://www.cnblogs.com/ngnetboy/archive/2012/11/23/2784078.html

1 #include<stdio.h>
2 #include<stdlib.h>
3 int main(void)
4 {
5 int j;
6 for(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),应该是这样的了。代码如下:

1 #include<stdio.h>
2 #include<stdlib.h>
3 int main(void)
4 {
5 int i;
6 for(i=0;i<3;i++)
7 {
8 d=rand();
9 c=1 + (10*d/(RAND_MAX));
10 printf("1 + (10*rand()/(RAND_MAX+1)):%d\n",c);
11 }
12
13 }

运行结果如下:

好像也达到我们的效果了。但是如果把这段代码放到linux下用gcc编译又是什么样的结果呢?
同样的代码,我们来看看结果

这是怎么回事?为什么同样的代码,到了另一个编译器后就不一样了?
还记得我们刚才分别在这两个编译器中求的RAND_MAX的值吗?对,vc中是32767,而gcc中是2147483647。这时候你该问了跟这个有关系吗?我可以十分肯定的告诉你,相当的有关系。我们来写个小程序验证我的猜想吧!代码如下:

1 #include<stdio.h>
2 #include<stdlib.h>
3 int main(void)
4 {
5 int i,a,d;
6 for(i=0;i<5;i++)
7 {
8 d=rand();
9 a=d*10;
10 printf("%d",sizeof(int));
11 printf("rand()*10:%d\n",a);
12 }
13 }

运行结果如下:

你看出有什么不一样了吗?对,这就是vc为什么对rand()函数的RAND_MAX的值进行修改了。在gcc中rand()的取值范围是0~32位的二进制数,如果拿这个随机数乘以10的话,很可能会发生数值溢出,也就是说gcc中int的值最大就取到2147483647,如果乘以10的话,只能接着往后排列了,-2147483647、-2147483646、-2147483645········一直到取得的那个值。所以会得到一些负数。
到了这里我想你应该知道解决的办法了吧~!没错,就是用一个double类型的数来接收rand()*10,我们没办法改变RAND_MAX的值,我们可以用更大的数来表示rand()*10。
这下应该可以了吧,我们修改一下代码看看效果:

1 #include<stdio.h>
2 #include<stdlib.h>
3 int main(void)
4 {
5 int i,a,d;
6 for(i=0;i<5;i++)
7 {
8 printf("(int)(10.0*rand()/(RAND_MAX+1.0)):%d\n",1+(int)(10.0*d/(RAND_MAX+1.0)));
9 }
10 }

运行结果如下:

对,这就是我们想要的结果了!
PS——函数会随着编译器的不同而效果不同,但是它终究逃不过开发者的眼睛,注意细节。
附加:
取0-1之间的浮点型值:

1 #include <stdio.h>
2 #include<stdlib.h>
3 #include<time.h>
4
5 int main(void)
6 {
7 int i;
8 float a;
9 srand((unsigned)time(NULL));
10 for(i=0;i<10;i++)
11 {
12 printf("%.1f\n",rand()/(RAND_MAX+0.1));
13 }
14 }

srand()函数是设置随机数的种子,由前面的推论可知rand()函数只是一个伪随机函数,srand()函数就是为rand()函数设置种子;time()函数是获取当前的时间,因此第九行代码就是为rand()函数设置一个根据系统时间变化的随机种子,这样代码在每次运行的时候的结果都不会一样了!
【C】揭秘rand()函数;的更多相关文章
- srand()以及rand()函数用法
srand()就是给rand()提供种子seed 如果srand每次输入的数值是一样的,那么每次运行产生的随机数也是一样的, srand(n) for(10) rand()也就是说,以一个固定的数值作 ...
- MySQL使用rand函数实现随机数[转]
如何写一个语句能一下更新几百条MYSQL数据! 需要测试MYSQL数据库,里面有一个上万条数据的数据库,如何写一个PHP文件一下每次更新几百条信息,我都是写一个循环一次更新一条信息,这样我知道用WHI ...
- Matlab中Rand()函数用法
一.理论准备 matlab函数randn:产生均值为0,方差 σ^2 = 1,标准差σ = 1的正态分布的随机数或矩阵的函数. 用法:Y = randn(n),返回一个n*n的随机项的矩阵.如果n不是 ...
- 关于 rand() 函数返回值的值域的疑问
<C语言参考手册>中关于 rand() 函数有如下描述. (1)rand() 函数的原型 int rand(void); (2)连续调用 rand 将返回 0 到 int 类型的最大可表示 ...
- C random C ++rand函数应用
random函数不是ANSI C标准,不能在gcc,vc等编译器下编译通过.但在C语言中int random(num)能够这样使用,它返回的是0至num-1的一个随机数. 可改用C++下的rand函数 ...
- RAND函数和SRAND函数
首先我们要对rand&srand有个总体的看法:srand初始化随机种子,rand产生随机数,下面将详细说明. rand(产生随机数) 表头文件: #include<stdlib.h&g ...
- C语言中生产随机数 rand()函数
参考资料:C语言中产生随机数 一:如果你只要产生随机数而不需要设定范围的话,你只要用rand()就可以了:rand()会返回一随机数值, 范围在0至RAND_MAX 间.RAND_MAX定义在stdl ...
- 关于rand()函数 转载于其他人
C++中的rand()函数 分类: 编程语言/ C#/ 文章 C++中产生随机数种子对于初学者一直都很困惑.大家知道,在C中有专门的srand(N)函数可以轻松实现这一功能,然而在C++中则要复杂一些 ...
- mysql的rand函数
项目中需要动态随机生成一些固定位数的随机数,如8位,5位等. 之前看到的写法是这样 ROUND(ROUND(RAND(),5)*100000) 这样写不太准确,有几率出现4位的情况,Rand() 函数 ...
随机推荐
- dmidecode查看硬件信息
//check memory,cpu,system,biosroot@dellemc-diag-os:/home# dmidecode -t Memoryroot@dellemc-diag-os:/h ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 排版:可滚动
<!DOCTYPE html> <html> <head> <title>菜鸟教程(runoob.com)</title> <meta ...
- 【转】python中的闭包详细解析
一.什么是闭包? 如果一个内嵌函数访问外部嵌套函数作用域的变量,并返回这个函数,则这个函数就是闭包 闭包必须满足三个条件: 1. 必须有一个内嵌函数 2. 内嵌函数必须引用外部嵌套函数中的变量 ...
- LeetCode困难题(一)
题目一: 给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度. 如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序. 示例 ...
- centso7设置防火墙
CentOS 7默认使用的是firewall作为防火墙,使用iptables必须重新设置一下 1.直接关闭防火墙 1 2 3 systemctl stop firewalld.service #停止f ...
- ffmpeg-01-Subtitle
1. ffmpeg简介 2. 摘录文档 2.1 过滤 Filtering 2.1.1 简单滤镜 2.1.2 复杂的滤镜 2.1.3 简单过滤与复杂过滤 2.2 Stream 流复制 2.3 对比图 3 ...
- 傅盛读书笔记:下一个Moonshot是什么?
猎豹移动CEO 傅盛 九月底,我有幸在硅谷拜访了苹果前CEO斯卡利.老人如今已经75岁高龄,但看起来仍充满活力.他花了一上午的时间跟我们沟通,非常谦和.平等.坦诚,给我留下了很深的印象.末了,给我们介 ...
- linux系统登陆过程
一.物理直连登陆过程 初始化进程init 会根据直接连接的字符终端设备,打开getty程序,并关联在字符终端设备上tty1/2/3/4/5/6/7....上,在不同的终端设备上提示用户输入信息,等待终 ...
- 分享Linux CentOS7 VMware 系统目录结构、 ls命令 、文件类型、alias命令——笔记
一. 系统目录结构 生成目录树结构: tree -a 显示所有 tree -d 仅显示目录 tree -L n n代表数字..表示要显示几层... tree -f 显示完整路径.. yum insta ...
- Lognormal distribution 对数正态分布
转载:https://blog.csdn.net/donggui8650/article/details/101556041 在概率论中,对数正态分布是一种连续概率分布,其随机变量的对数服从正态分布. ...