C++11 random numbers

2019-01-17 21:09发布

问题:

I need to generate random numbers, but from as wide a range as possible (64 bit at least). I don't care if the distribution is perfect, so std::rand() would work, but it only returns an int. I understand that c++11 has some random number generating capability that can give any size number, but is very complex to use. Can someone post a simple example of how to use it as simply as possible to get the described functionality (64 bit or more random numbers) in as simple a way as possible (like std::rand())?

回答1:

This is how to use the C++11 random number generation for this purpose (adjusted from http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution):

#include <random>
#include <iostream>
int main()
{
  /* Initialise. Do this once (not for every
     random number). */
  std::random_device rd;
  std::mt19937_64 gen(rd());

  /* This is where you define the number generator for unsigned long long: */
  std::uniform_int_distribution<unsigned long long> dis;

  /* A few random numbers: */    
  for (int n=0; n<10; ++n)
    std::cout << dis(gen) << ' ';
  std::cout << std::endl;
  return 0;
}

Instead of unsigned long long, you could use std::uintmax_t from cstdint to get the largest possible integer range (without using an actual big-integer library).



回答2:

We could easily wrap a random number generator engine into srand/rand-like methods like this:

#include <random>
#include <iostream>

struct MT19937 {
private:
    static std::mt19937_64 rng;
public:
    // This is equivalent to srand().
    static void seed(uint64_t new_seed = std::mt19937_64::default_seed) {
        rng.seed(new_seed);
    }

    // This is equivalent to rand().
    static uint64_t get() {
        return rng();
    }
};

std::mt19937_64 MT19937::rng;


int main() {
    MT19937::seed(/*put your seed here*/);

    for (int i = 0; i < 10; ++ i)
        std::cout << MT19937::get() << std::endl;
}

(Like srand and rand, this implementation does not care about thread-safety.)

Well the wrapper functions are so trivial that you could just use the engine directly.

#include <random>
#include <iostream>

static std::mt19937_64 rng;

int main() {
    rng.seed(/*put your seed here*/);

    for (int i = 0; i < 10; ++ i)
        std::cout << rng() << std::endl;
}


回答3:

Not C++11, but easy enough

((unsigned long long)rand() << 32) + rand() Here we generate two parts of int64 as int32's

As JasonD pointed out, it assumes that rand() generate 32bit integer. It' spossible to xor rand() << x, rand() << (2*x), rand() << (3*x), etc, where x <= bit's in generate by rand() number`. It should be OK too.



标签: c++ random c++11