更多课程 选择中心

C/C++培训
达内IT学院

400-111-8989

C/C++rand随机数函数知识讲解

  • 发布:ssp君
  • 来源:华水极客乐园官微
  • 时间:2017-11-27 10:16

首先已知的事实是,VC++以及别的C/C++编译器都将随机数函数外部化了,它们都使用线性同余算法来实现自己简单的随机数函数,以下是笔者在VC++6.0的代码文件中找到的rand函数的源代码。所有代码被凡在一个名为RAND.C的文件中。

其中的宏_MT是在多线程编程中使用的,我们一般的程序默认不是这个编译器选项,因此根据代码,我们只需要看宏else块里的内容。代码定义了一个静态全局变量holdrand,然后一般来说我们写程序时,通过srand设定随机数种子(使用Time函数),将输入数据格式化为long类型存入holdrand,并在你调用rand函数时,通过线性同余算法(迭代计算holdrand)直接返回结果。


根据参考内容1,这个算法是在1949年由D.H.Lehmer提出的,原书对该算法各参数的选取做了详细讨论,原文内容比较难懂,但是我们还是可以在里面找到一些有趣的东西。上面的代码的数学表达式如下:


mod运算在VC源码中是最后的与操作(双目算符&),下一个数值取为运算后的二进制数的低32位,高位抛弃。作者在书中举了个例子,然后说明了一个道理,这类迭代算法得到的数列是循环的:


但是我们可以人为的选取一些特殊的数,使得对于不同的初始值迭代函数的周期都可以较大。接下来是长篇大论的选取方法和数理推导。因此在VC++的源代码里面我们可以看到如此的rand实现。这里还有一张参数表,记录了不同的语言和编译器使用线性同余算法制造伪随机数的各参数取值。


按照这种方法处理的伪随机数的安全性不高。比如对于一个游戏工程或程序安全措施仅仅使用rand生成随机数,我们可以在运行着的内存中找到holdrand然后穷举整个周期里的所有数值,相当于我们可以按照现在的holdrand预测所有接下来的holdrand,即得知所有接下来的伪随机数值。因此使用rand在某些情况下是很不安全的。

另一个关于随机数的事实是,Windows系统实际上有随机数生成API,名称是CryptGenRandom。它是Advapi32库中的函数,包含于头文件Wincrypt.h。这个库是用于加密解密的,更多时候用在安全领域(当然一些病毒程序也会用它),因此有一个比VC++源代码更好的伪随机数生成的实现。根据MSDN上的介绍,该函数是deprecated类型的(不再被推荐使用),很有可能在将来微软会将其从系统dll文件中删除(到时候你依然可以在C程序中嵌入旧版本的lib然后使用该函数)。有兴趣的同学可以去看看,下面贴上MSDN基本介绍:


参考内容:

1. 想学算法的可以看看这套书,确实一坑货:《The Art of Computer Programming, Volume 2_ Seminumerical Algorithms (3rd Edition)》

2. 参数表来自blog:#/?p=741

预约申请免费试听课

填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:值得学习的C/C++语言开源项目
下一篇:C++11新特性 - 将sizeof用于类成员

C语言创建windows窗口实例

C++回调函数是什么?

C++ shared_ptr和动态数组

C语言有哪些关键词,C语言44个关键词大全

  • 扫码领取资料

    回复关键字:视频资料

    免费领取 达内课程视频学习资料

  • 搜索抖音号

    搜索抖音号:1821685962

    免费领取达内课程视频学习资料

Copyright © 2021 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省