I'd like to complement Shoe's and peterchen's excellent answers with a short overview of the state of the art in 2015:
Some good choices
randutils
The randutils
library (presentation) is an interesting novelty, offering a simple interface and (declared) robust random capabilities. It has the disadvantages that it adds a dependence on your project and, being new, it has not been extensively tested. Anyway, being free (MIT License) and header-only, I think it's worth a try.
Minimal sample: a die roll
#include <iostream>
#include "randutils.hpp"
int main() {
randutils::mt19937_rng rng;
std::cout << rng.uniform(1,6) << "\n";
}
Even if one is not interested in the library, the website provides many interesting articles about the theme of random number generation in general and the C++ library in particular.
Boost.Random
Boost.Random
(documentation) is the library which inspired C++11's <random>
, with whom it shares much of the interface. While theoretically also being an external dependency, Boost has by now a status of "quasi-standard" library, and its Random
module could be regarded as the classical choice for good-quality random number generation. It features two advantages with respect to the C++11 solution:
- it is more portable, just needing compiler support for C++03
- its
random_device
uses system-specific methods to offer seeding of good quality
The only small flaw is that the module offering random_device
is not header-only, one has to compile and link boost_random
.
Minimal sample: a die roll
#include <iostream>
#include <boost/random.hpp>
#include <boost/nondet_random.hpp>
int main() {
boost::random::random_device rand_dev;
boost::random::mt19937 generator(rand_dev());
boost::random::uniform_int_distribution<> distr(1, 6);
std::cout << distr(generator) << '\n';
}
While the minimal sample does its work well, real programs should use a pair of improvements:
- make
mt19937
a thread_local
: the generator is quite plump (more than 2 KB) and is better not allocated on the stack
- seed
mt19937
with more than one integer: the Mersenne Twister has a big state and can take benefit of more entropy during initialization
Some not-so-good choices
The C++11 library
While being the most idiomatic solution, the <random>
library does not offer much in exchange for the complexity of its interface even for the basic needs. The flaw is in std::random_device
: the Standard does not mandate any minimal quality for its output (as long as entropy()
returns 0
) and, as of 2015, MinGW (not the most used compiler, but hardly an esoteric choice) will always print 4
on the minimal sample.
Minimal sample: a die roll
#include <iostream>
#include <random>
int main() {
std::random_device rand_dev;
std::mt19937 generator(rand_dev());
std::uniform_int_distribution<int> distr(1, 6);
std::cout << distr(generator) << '\n';
}
If the implementation is not rotten, this solution should be equivalent to the Boost one, and the same suggestions apply.
Godot's solution
Minimal sample: a die roll
#include <iostream>
#include <random>
int main() {
std::cout << std::randint(1,6);
}
This is a simple, effective and neat solution. The only defect is it will take a while to compile – about two years, providing C++17 is released on time and the experimental randint
function is approved into the new Standard. Maybe by that time also the guarantees on the seeding quality will improve.
Minimal sample: a die roll
#include <cstdlib>
#include <ctime>
#include <iostream>
int main() {
std::srand(std::time(nullptr));
std::cout << (std::rand() % 6 + 1);
}
The old C solution is considered harmful, and for good reasons (see the other answers here or this detailed analysis). Still, it has its advantages: is is simple, portable, fast and honest, in the sense it is known that the random numbers one gets are hardly decent, and therefore one is not tempted to use them for serious purposes.
The accounting troll solution
Minimal sample: a die roll
#include <iostream>
int main() {
std::cout << 9; // http://dilbert.com/strip/2001-10-25
}
While 9 is a somewhat unusual outcome for a regular die roll, one has to admire the excellent combination of good qualities in this solution, which manages to be the fastest, simplest, most cache-friendly and most portable one. By substituting 9 with 4, one gets a perfect generator for any kind of Dungeons & Dragons die, while still avoiding the symbol-laden values 1, 2 and 3. The only small flaw is that, because of the bad temper of Dilbert's accounting trolls, this program actually engenders undefined behavior.
rand()
was uniform. Which library are you using?cstdlib.h
'srand()
is NOT uniform: cplusplus.com/reference/cstdlib/rand – Unexpected