随机数:真随机数和伪随机数

c语言中的伪随机数详解

既然我们已经了解了真伪随机数的概念,接下来就来探究一下离我们最近的伪随机数吧。

c语言中就存在一个随机函数:rand().它就是一个标准的伪随机数生成器。依赖的头文件是stdlib.h.

接下来我就使用rand函数,来试着产生一些随机数。

#include <stdio.h>
#include <stdlib.h>
 
int main ()
{
       int random = rand();
    printf("%d\n",random);
    random = rand();
    printf("%d\n",random);
    random = rand();
    printf("%d\n",random);
}

这里我使用一个整形变量来接受rand函数产生的随机数,并对其进行打印。
在这里插入图片描述

执行后,成功看到了结果。貌似是一串随机数。
可是,当我们多次执行时,发现它的数值却还是41,18467, 6334。

这并不是我们想要的结果,我们希望每一次运行都可以产生不同的数值。可是如何解决这个问题呢?

其实,在c语言中的rand函数中有一个定义叫做种子,rand函数是通过对这个种子进行一系列的运算来模拟出一个随机数的。我们直接调用rand函数,并不指定种子,系统就会调用默认的种子:1,来产生随机数。因为每次重新运行时的种子都是1,运行出来的结果自然就还是这几个数啦。

现在我们已经知道了种子这个重要的参数,我们就可以用一个一元二次方程来模拟这个过程。

例如,rand函数的内部实现为 x^2 + 4x - 8,这个种子就相当于x。
如果想要改变rand最终的值,只能通过改变x来实现。

那么,既然要产生随机数,x就应该是一直在不断变化的,才能让x^2 + 4x - 8这个表达式的值不断的变化。

x,也就是种子,该采用什么东西呢?

没错,最理想的就是时间了。时间每分每秒都在变动,正好符合我们的要求。这里需要使用到time.h。

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
 
int main ()
{
	srand ((unsigned)time(NULL));
	int random = rand();
	printf("%d\n",random);
	random = rand();
	printf("%d\n",random);
	random = rand();
	printf("%d\n",random);
}

对之前的代码进行改进。通过时间设置种子的值:srand ((unsigned)time(NULL));
这时候再运行,每次都会得出不同的结果了。

这里srand函数的定义就是:随机数生成器的初始化函数。通常是和rand函数配合使用的。

函数原型:srand(unsigned seed)

代码中的time(NULL)将返回计算机目前的时刻与1970年1月1日0时0分0秒之间的时间差,单位是秒。

srand又需要unsigned int类型,所以这里使用一个强制类型转换,最后完成种子的设置。

需要注意的是,srand函数必须放在循环或者循环调用的外面,否则还是会得出重复的数字。

到这里,就可以产生你想要的随机数了。如果你想在0~4之间产生随机数,只需要int random = rand()%4,这样每次出来的随机数就会在0-4中了。

那么,我想让产生的随机数在1-100范围内,用int random = rand()%100,这样行吗?
当然不行!!

是,没错,结果都是在范围内的。但是你如果短时间内连续执行,会发现它是有规律可循的,会随着时间的推移慢慢上涨,到100后再回到0,再重新上涨…

这可是个严重的问题。游戏如果敢这么做,肯定会亏的妻离子散。

所以,这个办法只能用于范围较小的随机数,应用范围非常窄。

通用的一个方法是 (int)(n*rand()/(RAND_MAX+1.0)),这样产生随机数的周期会大大缩短,从而达到我们想要的效果。

转载自:https://blog.csdn.net/czc1997/article/details/78167705

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值