Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Generating Random Numbers
PrevUpHomeNext

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>

int main()
{
   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;
   return 0;
}

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>

int main()
{
   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;

   return 0;
}

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>

int main()
{
   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;
   return 0;
}

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>

int main()
{
   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;
   return 0;
}

PrevUpHomeNext