美文网首页
正确生成随机数的两种姿势

正确生成随机数的两种姿势

作者: HAPPYers | 来源:发表于2019-08-12 16:25 被阅读0次

为什么不用rand()函数,可以看看https://codeforces.com/blog/entry/61587

使用RDSEEDRDRAND指令

RDSEED,RDRAND是两个汇编指令,通过硅片上的热噪声来生成随机数。

  • 从Intel Broadwell架构的 CPU 和AMD Zen架构的 CPU开始支持此指令
  • 在AMD和Intel的CPU上,可以使用CPUID指令来检测CPU是否支持RDRAND指令。如果支持该指令,调用CPUID的01号标准函数之后,ECX寄存器的第30位会被设置成1。
  • 从RDSEED指令获取输入流比从RDRAND获取要慢。

关于RDSEED和RDRAND指令的区别,文献很少。笔者从INTEL官网找到了相关文章。
大意就是如果打算用来作为其它伪随机数生成器(pseudorandom number generator)的种子的时候,可以使用RDSEED,其他情况则使用RNRAND

感兴趣的读者可以戳此https://software.intel.com/en-us/blogs/2012/11/17/the-difference-between-rdrand-and-rdseed

首先检测当前CPU是否支持RDRAND,我们通过调用CPUID的01号标准函数,根据执行后的ECX寄存器第30位是否为1来判断。如果为1,则支持。

cpuid
and eax, 0x20000000 //比较第30位
test eax, 0

核心代码就是rdrand eax将生成的随机数放到eax寄存器中

下面是自己写的生成100个随机数生成的代码,仅供参考。

#include <iostream>
using namespace std;
int main()
{
    bool flag = 0;
    unsigned int result = 0;
    __asm {
        mov eax, 1
        cpuid
        and eax, 0x20000000 //30th bit
        test eax, 0
        jnz L
        mov flag, 1
        L:
    }
    if (!flag) {
        cout << "Not support this CPU!";
        return 0;
    }
    for (int i = 0; i < 100; i++) {
        __asm {
            rdrand eax
            mov result, eax
        }
        cout << result << endl;
    }
    return 0;
}

使用mt19937

mt19937是什么?它是c++11中加入的新特性,是一种随机数算法。
总的一点,相对于传统的srand(),mt19937拥有更好的性能。
具有速度快,周期长的特点(它的名字便来自周期长度:2^19937-1)
rand()函数在windows下生成的数据范围为0-32767
但是这个mt19937的随机范围在(−MAXINT,+MAXINT)(其中MAXINT为int的最大值)

它的使用非常简单

#include<random>
#include<ctime>
std::mt19937 rnd(time(0));
int main()
{
    printf("%lld\n",rnd());
    return 0;
}

另外,random_shuffle使用的时自带的rand()
我们可以把rnd函数传入shuffle,使shuffle更随机

shuffle(a, a + n, rnd); //a为数组

这样就能让数组内的元素随机移动足够大的距离

关于mt19937具体可以见std::mt19937

相关文章

  • 正确生成随机数的两种姿势

    为什么不用rand()函数,可以看看https://codeforces.com/blog/entry/61587...

  • 多线程环境下生成随机数

    生成伪随机数据 Java里有伪随机型和安全型两种随机数生成器。伪随机生成器根据特定公式将seed转换成新的伪随机数...

  • 生成随机数

    两个C函数 rand()函数生成的随机数是伪随机数,所谓伪随机数,指的是程序每次运行,生成的随机数都是不变的,生成...

  • 在以太坊生成随机数的几种方式(含代码)

    一、什么是随机数 随机数都是由随机数生成器(Random Number Generator)生成的。随机数分为”真...

  • 生成五个不同的随机数

    对于生成几个互不相同的随机数应用的还挺广泛的,接触js还没多长时间,给大家分享两种方法来生成不重复的随机数。 1....

  • PHP生成随机数

    PHP生成随机数,相信大家在做项目的时候是最常见的吧。js生成随机数,PHP生成随机数。 应用场景:用户注册/登录...

  • Golang生成随机数的方法总结

    生成区间随机数 生成指定区间随机数(包括纯数字/纯字母/随机)

  • Excel怎么生成随机数?

    Excel怎么生成随机数?如何生成指定范围内的随机数呢?可以在Excel中使用函数,生成随机数。 1、在单元格中输...

  • go生成随机数字和固定长度字符串

    生成随机数字 go可以通过math/rand包来生成随机数在生成随机数之前,需要一个种子,用于整个过程的初始化,否...

  • 无处不在的随机数

    目录: 什么是随机数 随机数分类 伪随机数生成器 真随机数生成器 各种语言中的随机数 使用系统时间作为种子是否安全...

网友评论

      本文标题:正确生成随机数的两种姿势

      本文链接:https://www.haomeiwen.com/subject/hrkdyqtx.html