...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Random numbers are generated in conjunction with Boost.Random. However, since Boost.Random is unaware of arbitrary precision numbers, it's necessary to include the header:
#include <boost/multiprecision/random.hpp>
In order to act as a bridge between the two libraries.
Integers with N random bits are generated using independent_bits_engine
:
#include <boost/multiprecision/gmp.hpp> #include <boost/multiprecision/random.hpp> using namespace boost::multiprecision; using namespace boost::random; // // Declare our random number generator type, the underlying generator // is the Mersenne twister mt19937 engine, and 256 bits are generated: // typedef independent_bits_engine<mt19937, 256, mpz_int> generator_type; generator_type gen; // // Generate some values: // std::cout << std::hex << std::showbase; for(unsigned i = 0; i < 10; ++i) std::cout << gen() << std::endl;
Alternatively we can generate integers in a given range using uniform_int_distribution
, this will invoke
the underlying engine multiple times to build up the required number of bits
in the result:
#include <boost/multiprecision/gmp.hpp> #include <boost/multiprecision/random.hpp> using namespace boost::multiprecision; using namespace boost::random; // // Generate integers in a given range using uniform_int, // the underlying generator is invoked multiple times // to generate enough bits: // mt19937 mt; uniform_int_distribution<mpz_int> ui(0, mpz_int(1) << 256); // // Generate the numbers: // std::cout << std::hex << std::showbase; for(unsigned i = 0; i < 10; ++i) std::cout << ui(mt) << std::endl;
Floating point values in [0,1) are generated using uniform_01
,
the trick here is to ensure that the underlying generator produces as many
random bits as there are digits in the floating point type. As above independent_bits_engine
can be used for
this purpose, note that we also have to convert decimal digits (in the floating
point type) to bits (in the random number generator):
#include <boost/multiprecision/gmp.hpp> #include <boost/multiprecision/random.hpp> using namespace boost::multiprecision; using namespace boost::random; // // We need an underlying generator with at least as many bits as the // floating point type to generate numbers in [0, 1) with all the bits // in the floating point type randomly filled: // uniform_01<mpf_float_50> uf; independent_bits_engine<mt19937, 50L*1000L/301L, mpz_int> gen; // // Generate the values: // std::cout << std::setprecision(50); for(unsigned i = 0; i < 20; ++i) std::cout << uf(gen) << std::endl;
Finally, we can modify the above example to produce numbers distributed according to some distribution:
#include <boost/multiprecision/gmp.hpp> #include <boost/multiprecision/random.hpp> using namespace boost::multiprecision; using namespace boost::random; // // We can repeat the above example, with other distributions: // uniform_real_distribution<mpf_float_50> ur(-20, 20); gamma_distribution<mpf_float_50> gd(20); independent_bits_engine<mt19937, 50L*1000L/301L, mpz_int> gen; // // Generate some values: // std::cout << std::setprecision(50); for(unsigned i = 0; i < 20; ++i) std::cout << ur(gen) << std::endl; for(unsigned i = 0; i < 20; ++i) std::cout << gd(gen) << std::endl;