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.