一、rand和srand

  在C++11标准出来之前,C/C++都依赖于stdlib.h头文件的rand或者srand来生成随机数。

  其不是真正的随机数,是一个伪随机数,是根据一个数(我们可以称它为种子)为基准以某个递推公式推算出来的一系列数,当这系列数很大的时候,就符合正态公布,从而相当于产生了随机数,但这不是真正的随机数,当计算机正常开机后,这个种子的值是定了的,除非你破坏了系统。

  • rand:内部是线性同余实现的,因为周期较长,所以在一定的范围内可看成随机的。系统默认随机种子是1。rand()返回一随机数值的范围在0至RAND_MAX 间。RAND_MAX的范围最少是在32767之间(int)。用unsigned int 双字节是65535,四字节是4294967295的整数范围。0~RAND_MAX每个数字被选中的机率是相同的。
//函数声明
int rand(void);
  • srand:srand()用来设置rand()产生随机数时的随机数种子。参数seed必须是个整数,如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。
//函数声明
void srand(unsigned int seed);
  • 常见用法如下:

    • (rand() % (b - a)) + a ,生成[a, b) 的随机整数
    • (rand() % (b - a + 1)) + a ,生成[a,b] 的随机整数
    • rand() / double(RAND_MAX) ,生成0~1之间的浮点数
  • 来个测试代码:

#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main()
{
srand((unsigned)time(NULL));
for(int i = 0; i < 10;i++ )
cout << rand() << '\t';
cout << endl;
return 0;
}

二、新标准随机数

  有时候程序员需要一些非均匀分布的数,这时候rand就显得不是那么好用,新标准很好解决了这个问题:随机数引擎类随机数分布类。引擎用来生成随机unsigned整数序列,分布则使用引擎返回服从特定概率分布的随机数。

  标准库定义了多个随机数引擎类,区别在于性能和随机性质量不同。每个编译器都会指定其中一个作为default_random_engine类型。标准库定义的引擎通用操作如下:

操作 解释
Engine e 默认构造函数,使用该引擎默认的种子
Engine e(s) 使用整型值s作为种子
e.seed(s) 使用种子s重置引擎的状态
e.max(), e.min() 该引擎可生成的最大和最小值
Engine::result_type 该引擎生成的unsigned整型类型
e.discard(u) 将引擎推进u步,u为unsigned long long类型

  对于大多数场合,随机数引擎的输出是不能直接使用的,还要配合合适的分布类。均匀分布类为uniform_int_distribution<unsigned>。标准库中的分布类的通用操作如下:

操作 解释
Dist d 默认构造函数
d(e) 用相同的引擎e连续生成随机数序列
d.max(), d.min() 返回d(e)能生成的最大和最小值
d.reset() 重建d的状态,使得随后对d的使用不依赖于d已经生成的值

  以下为简单测试:

#include <iostream>
#include <random> using namespace std; int main() {
//0~9的均匀分布
uniform_int_distribution<unsigned> u(0,9);
//若想生成0~1的double
//uniform_int_distribution<double> u(0,1);
default_random_engine e;
for(size_t i = 0; i < 10; i++)
cout << u(e) << " ";
//由于是默认的种子,所以应该都是0 1 7 4 5 2 0 6 6 9
return 0;
}

  为了生成不同的结果,我们可以通过设置种子,为引擎设置种子的方法有两种方式:在创建引擎对象的时候提供种子,或者调用引擎的seed成员。简单测试如下:

#include <iostream>
#include <random> using namespace std; int main() {
default_random_engine e1; //默认种子
default_random_engine e2(2147483646); //给定的种子
default_random_engine e3;
e3.seed(32767); //调用成员seed
default_random_engine e4(32767); //和e3一样的种子
uniform_int_distribution<unsigned> u(0,9);
for(size_t i = 0; i < 10; i++)
cout << u(e1) << " " << u(e2) << " " << u(e3) << " " << u(e4) << endl;
return 0;
}

  除了均匀分布下生成unsined整数,我们还可以生成不同分布下别的类型的数值。比如uniform_real_distribution<> u(0,1)生成0~1的double类型值,还有normal_distribution<> n(4,1.5)生成均值为4,标准差为1.5的正态分布double类型值。

实际上,新标准定义了20种分布类型,如有需要,请翻阅C++11文档。

C/C++生成随机数的更多相关文章

  1. .Net使用system.Security.Cryptography.RNGCryptoServiceProvider类与System.Random类生成随机数

    .Net中我们通常使用Random类生成随机数,在一些场景下,我却发现Random生成的随机数并不可靠,在下面的例子中我们通过循环随机生成10个随机数: ; i < ; i++) { Rando ...

  2. DotNet生成随机数的一些方法

    在项目开发中,一般都会使用到“随机数”,但是在DotNet中的随机数并非真正的随机数,可在一些情况下生成重复的数字,现在总结一下在项目中生成随机数的方法. 1.随机布尔值: /// <summa ...

  3. Oracle中生成随机数的函数(转载)

    在Oracle中的DBMS_RANDOM程序包中封装了一些生成随机数和随机字符串的函数,其中常用的有以下两个: DBMS_RANDOM.VALUE函数 该函数用来产生一个随机数,有两种用法: 1. 产 ...

  4. JAVA生成随机数

    java中一般有两种随机数,一个是Math中random()方法,一个是Random类. 一.Math.random() 随即生成0<x<1的小数. 实例:如何写,生成随机生成出0~100 ...

  5. iOS开发-生成随机数

    有时候我们需要在程序中生成随机数,但是在Objective-c中并没有提供相应的函数,好在C中提供了rand().srand().random().arc4random()几个函数.那么怎么使用呢?下 ...

  6. exce生成随机数

    有时候数据库没有数据,造数据专用. 来源于:http://jingyan.baidu.com/article/93f9803feba1f5e0e46f55f2.html 首先介绍一下如何用RAND() ...

  7. 【gsl】生成随机数

    来自:http://hsxqwanting.blog.163.com/blog/static/16945437201301042830815/ 使用GSL生成随机数时的三个步骤:    (1)gsl_ ...

  8. loadrunner生成随机数

    loadrunner生成随机数一: 对网站注册进行压力测试时,需要对注册的用户名进行参数化,因为可以会用到大量的测试数据,所以选择通过生成随机数来进行参数化.最开始用loadrunner自带的参数随机 ...

  9. php生成随机数的三种方法

    php生成随机数的三种方法 如何用php生成1-10之间的不重复随机数? 例1,使用shuffle函数生成随机数. <?php$arr=range(1,10);shuffle($arr);for ...

  10. C# random生成随机数全部一样

    最近做排序测试  使用random生成随机数全部一样 估计是因为random采用的随机种子为时间戳 而一个循化执行消耗的时间没有到时间戳的最小单位 故没有变化 Thread.Sleep(10); 使用 ...

随机推荐

  1. window.load 和$(document).ready() 区别

    1.执行时间 window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行. $(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕.2.编写个数不同 w ...

  2. Python爬虫 股票数据爬取

    前一篇提到了与股票数据相关的可能几种数据情况,本篇接着上篇,介绍一下多个网页的数据爬取.目标抓取平安银行(000001)从1989年~2017年的全部财务数据. 数据源分析 地址分析 http://m ...

  3. djang-tastypie学习整理

    quick start: 配置环境(pip install: Python 2.7+ or Python 3.4+ Django 1.8+ python-mimeparse 0.1.4+ (http: ...

  4. Mybatis动态SQL单一基础类型参数用if标签

    Mybatis动态SQL单一基础类型参数用if标签时,test中应该用 _parameter,如: 1 2 3 4 5 6 <select id="selectByName" ...

  5. [转]Ubuntu Linux 安装 .7z 解压和压缩文件

    [转]Ubuntu Linux 安装 .7z 解压和压缩文件 http://blog.csdn.net/zqlovlg/article/details/8033456 安装方法: sudo apt-g ...

  6. Python的Argparse模块是什么?(未完)

            近日在阅读代码的过程中遇到了Argparse模块,记得前段时间已经看了,可是过了两周现在又忘了, 看来写代码一定要钻研到底搞清楚其中原委才行,本文主要参考Python3.6系列官方文档 ...

  7. 一步步教你开发、部署第一个去中心化应用(Dapp) - 宠物商店

    今天我们来编写一个完整的去中心化(区块链)应用(Dapps), 本文可以和编写智能合约结合起来看. 写在前面 阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以太坊是什么除此之 ...

  8. 第一周CoreIDRAW课总结

      一. 问:这节课学到了什么知识? 答:这节课我学到了很多知识,作为初学者的我,老师给我讲了CorelDEAW的启动,安装,基础知识和应用与用途. 基础知识 位图:是由无数个像素点构成的图像,又叫点 ...

  9. LinkedList源码解析(JDK1.8)

    package java.util; import java.util.function.Consumer; /** * LinkedList是List和Deque接口的双向链表的实现.实现了所有可选 ...

  10. 1-6 hibernate映射集合属性

    1.集合类框架 以Tree开头都是按顺序,默认情况下是升序排列. 以Linked 开头的都是按插入顺序排列的. 2.在hibernate中要持久化集合属性时必须将其声明为接口,如 private Se ...