Skip to content

2.5 generating random numbers

Zhihao Yuan edited this page May 15, 2013 · 3 revisions

Solution

template <typename T>
T irand(T from, T to) {
	static auto seed = std::random_device{}();
	static std::default_random_engine e{seed};
	static std::uniform_int_distribution<T> d{from, to};
	return d(e);
}

Then use irand(from, to) to generate pseudo random numbers within the range [ from, to ].

Discussion

The random generator rand in C standard library is broken in (at least) two aspects:

  1. It asks the user to implement a distribution, which is very hard to non-experts to implement correctly (without bias), even a uniform distribution.
  2. Its underlying pseudo random number engine is implementation-defined, which makes the library not cryptographically secure.

The C++11 random number facilities address the problems with two concepts: Engine and Distribution. For a given engine e and a distribution d of type T, d(e) is a Generator which yields a random number of type T for each call to the generator.

There is an existing type of generator, std::random_device, which may be associated to a hardware device, thus, a good candidate for the seeding purpose.

An engine is seeded when it's initialized. If you want a determined sequence of "random" numbers for debugging purpose, you can default initialize the engine:

std::default_random_engine e1;

There are 20 twenty distribution types available in the standard library. Most of them are for statistic purpose, for example, the std::normal_distribution.

See also

Random Number Generation in C++11 http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3551.pdf

Clone this wiki locally