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

时间:2021-11-07 16:52:08

Standard rand() function gives numbers not big enough for me: I need unsigned long long ones. How do we get really big random numbers? I tried modifying a simple hash function but it's too big, takes too long to run and never produces numbers which are less than 1e5!!

函数给出的数字对我来说不够大:我需要无符号的长数据。如何得到大随机数呢?我尝试修改一个简单的哈希函数,但是它太大,运行时间太长,而且从不生成小于1e5的数字!!

6 个解决方案

#1


9  

Here's a portable C99 solution that returns a random 64-bit number:

这里有一个可移植的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;
}

Explanation: rand() returns integers in the range 0 to RAND_MAX and RAND_MAX is only guaranteed to be at least 32,767 (15 random bits). long long is guaranteed to have 64 bits but may be larger.

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

#2


16  

You can easily do this with std::uniform_int_distribution<unsigned long long>.

您可以使用std::uniform_int_distribution <无符号长> 轻松做到这一点。

Simple example code (taken from here, modified to use 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';
}

Note that the seeding of the mersenne twister as done here for demo purposes is not perfect, for example see here.

注意,mersenne绕射器的播种并不是完美的,比如这里。

#3


2  

If you want just to produce unsigned long long from value returned by rand() and do not care about the characteristics of the result consider the following function that must be compiler version and platform independent (because no "magic numbers" are used):

如果您只想从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;
}

But if you want some sequence of random numbers with certain predetermined characteristics, you should look in some specific guides or math books. E.g. https://www.gnu.org/software/gsl/manual/html_node/Random-number-generator-algorithms.html

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

#4


0  

You didn't ask for a specific OS and the answers here are really good, but on Linux (and probably on other OSes too) you can also read from a random device.

您没有要求特定的操作系统,这里的答案非常好,但是在Linux上(可能在其他操作系统上也是),您也可以从随机设备中读取。

Example:

例子:

#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;
}

Written on mobile, may have bugs. :P

在移动设备上写,可能有bug。:P

#5


0  

You can also use the boost library (taken from link):

你也可以使用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;
}

#6


-1  

try this:

试试这个:

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

#1


9  

Here's a portable C99 solution that returns a random 64-bit number:

这里有一个可移植的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;
}

Explanation: rand() returns integers in the range 0 to RAND_MAX and RAND_MAX is only guaranteed to be at least 32,767 (15 random bits). long long is guaranteed to have 64 bits but may be larger.

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

#2


16  

You can easily do this with std::uniform_int_distribution<unsigned long long>.

您可以使用std::uniform_int_distribution <无符号长> 轻松做到这一点。

Simple example code (taken from here, modified to use 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';
}

Note that the seeding of the mersenne twister as done here for demo purposes is not perfect, for example see here.

注意,mersenne绕射器的播种并不是完美的,比如这里。

#3


2  

If you want just to produce unsigned long long from value returned by rand() and do not care about the characteristics of the result consider the following function that must be compiler version and platform independent (because no "magic numbers" are used):

如果您只想从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;
}

But if you want some sequence of random numbers with certain predetermined characteristics, you should look in some specific guides or math books. E.g. https://www.gnu.org/software/gsl/manual/html_node/Random-number-generator-algorithms.html

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

#4


0  

You didn't ask for a specific OS and the answers here are really good, but on Linux (and probably on other OSes too) you can also read from a random device.

您没有要求特定的操作系统,这里的答案非常好,但是在Linux上(可能在其他操作系统上也是),您也可以从随机设备中读取。

Example:

例子:

#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;
}

Written on mobile, may have bugs. :P

在移动设备上写,可能有bug。:P

#5


0  

You can also use the boost library (taken from link):

你也可以使用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;
}

#6


-1  

try this:

试试这个:

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