Getting big random numbers in C/C++

≡放荡痞女 提交于 2019-11-27 05:08:40

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

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.

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

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.

VolAnd

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):

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

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.

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

You can also use the boost library (taken from 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;
}

try this:

long N=1000000;
long randNumber;
for(long i=0;i<N;i++)
randNumber=i+rand()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!