在 C/C++ 中获取大随机数

Getting big random numbers in C/C++

标准 rand() 函数给出的数字对我来说不够大:我需要 unsigned long long 个。我们如何获得真正大的随机数?我尝试修改一个简单的哈希函数,但它太 ,需要太长时间 运行 并且永远不会产生小于 1e5!!

的数字

您可以使用 std::uniform_int_distribution<unsigned long long> 轻松做到这一点。

简单示例代码(取自here,修改为使用unsigned long long):

#include <random>
#include <iostream>

int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<unsigned long long> dis(lowerBorder, upperBorder);

    for (int n=0; n<10; ++n)
        std::cout << dis(gen) << ' ';
    std::cout << '\n';
}

请注意,此处用于演示目的的梅森扭曲器的播种并不完美,例如请参见 here

这是一个便携式 C99 解决方案,returns 一个随机的 64 位数字:

unsigned long long llrand() {
    unsigned long long r = 0;

    for (int i = 0; i < 5; ++i) {
        r = (r << 15) | (rand() & 0x7FFF);
    }

    return r & 0xFFFFFFFFFFFFFFFFULL;
}

说明:rand() returns 0 到 RAND_MAXRAND_MAX 范围内的整数只能保证至少为 32,767(15 个随机位)。 long long 保证有 64 位,但可能更大。

您没有要求特定的 OS 并且这里的答案非常好,但是在 Linux 上(也可能在其他 OSes 上)您也可以阅读来自随机设备。

示例:

#include <stdio.h>
#include <assert.h>

#define RANDDEV "/dev/urandom"

unsigned long long bigrand(void) {
    FILE *rdp;
    unsigned long long num;

    rdp = fopen(RANDDEV, "rb");
    assert(rdp);

    assert(fread(&num, sizeof(num), 1, rdp) == 1);

    fclose(rdp);

    return num;
}

在手机上写的,可能有错误。 :P

如果您只想从 rand() 返回的值生成 unsigned long long 并且不关心结果的特征,请考虑以下必须与编译器版本和平台无关的函数(因为没有 "magic numbers"):

// this header has RAND_MAX value
#include <stdlib.h>  
// and this header has ULLONG_MAX
#include <limits.h>

unsigned long long ullrand()
// Produces pseudo-random numbers from 0 to ULLONG_MAX
// by filling all bits of unsigned long long integer number
// with bits of several "small" integer numbers generated by rand()
{
    unsigned long long myrndnum = 0; // at the beginning just zero
    unsigned long long counter = ULLONG_MAX; // at the beginning we have all bits set as 1
    // ... and while at least one bit is still set to 1
    while(counter > 0) {
           myrndnum = (myrndnum * (RAND_MAX + 1)) + rand(); // fill some bits from rand()
           counter /= (RAND_MAX + 1); // decrease number of 1-bits in counter
        }
    // Return the result
    return myrndnum;
}

但是如果您想要一些具有某些预定特征的随机数序列,您应该查看一些特定的指南或数学书籍。例如。 https://www.gnu.org/software/gsl/manual/html_node/Random-number-generator-algorithms.html

试试这个:

long N=1000000;
long randNumber;
for(long i=0;i<N;i++)
randNumber=i+rand()

您还可以使用 boost 库(取自 link):

#include <ctime>            // std::time
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/generator_iterator.hpp>


int main()
{
    long long my_min = 1;
    long long my_max = 1e5;

    boost::mt19937 generator(static_cast<unsigned int>(std::time(0)));
    boost::variate_generator<boost::mt19937&, boost::uniform_real<> >
        die_gen(generator, boost::uniform_real<> (my_min, my_max));

    boost::generator_iterator<boost::variate_generator<boost::mt19937&, boost::uniform_real<> > > die(&die_gen);

    std::cout<<"Generated random numbers: \n";
    for (int i=0; i <10 ; i++)
    {
        std::cout<< static_cast<long long>(*die++) << std::endl;
    }

    return 0;
}