繁体   English   中英

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

[英]Getting big random numbers in C/C++

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

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

简单的示例代码(从此处获取 ,修改为使用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';
}

请注意,此处出于演示目的而进行的mersenne Twister的播种并不完美,例如,请参见此处

这是一个可移植的C99解决方案,它返回一个随机的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()返回范围为0到RAND_MAX整数,并且仅保证RAND_MAX至少为32,767(15个随机位)。 long long保证具有64位,但可能更大。

如果您只想从rand()返回的值中产生长整型且不关心结果的特征,请考虑以下函数,该函数必须是编译器版本和平台无关的(因为未使用“幻数”):

// 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

您没有要求特定的操作系统,并且这里的答案确实不错,但是在Linux(可能还有其他操作系统)上,您也可以从随机设备中读取内容。

例:

#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

您还可以使用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;
}

尝试这个:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM