9

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

4

6 回答 6

17

您可以使用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 播种并不完美,例如,请参见此处

于 2015-01-23T17:53:06.923 回答
10

这是一个可移植的 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 位,但可能更大。

于 2015-01-23T18:06:18.337 回答
2

如果您只想从 rand() 返回的值生成 unsigned long long 并且不关心结果的特征,请考虑以下必须是编译器版本和平台独立的函数(因为不使用“幻数”):

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

于 2015-01-24T22:32:06.970 回答
0

您没有要求特定的操作系统,这里的答案非常好,但是在 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;
}

写在手机上,可能有bug。:P

于 2015-01-24T11:56:42.897 回答
0

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

#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;
}
于 2016-12-09T20:42:28.907 回答
-1

尝试这个:

long N=1000000;
long randNumber;
for(long i=0;i<N;i++)
randNumber=i+rand()
于 2016-03-28T18:35:07.053 回答