multiprecision_int_test.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /* multiprecision_int_test.cpp
  2. *
  3. * Copyright John Maddock 2015
  4. * Distributed under the Boost Software License, Version 1.0. (See
  5. * accompanying file LICENSE_1_0.txt or copy at
  6. * http://www.boost.org/LICENSE_1_0.txt)
  7. *
  8. * $Id$
  9. *
  10. * Tests all integer related generators and distributions with multiprecision types:
  11. * discard_block, independent_bits_engine, random_number_generator,
  12. * xor_combine_engine, uniform_int_distribution, uniform_smallint.
  13. *
  14. * Not supported, but could be with more work (but probably not worth while):
  15. * shuffle_order_engine, binomial_distribution, discrete_distribution, negative_binomial_distribution,
  16. * poisson_distribution
  17. */
  18. #define BOOST_TEST_MAIN
  19. #include <boost/test/unit_test.hpp>
  20. #include <boost/core/ignore_unused.hpp>
  21. #include <boost/multiprecision/debug_adaptor.hpp>
  22. #include <boost/multiprecision/cpp_bin_float.hpp>
  23. #include <boost/multiprecision/cpp_int.hpp>
  24. #include <boost/random/independent_bits.hpp>
  25. #include <boost/random/discard_block.hpp>
  26. #include <boost/random/xor_combine.hpp>
  27. #include <boost/random/mersenne_twister.hpp>
  28. #include <boost/random/random_number_generator.hpp>
  29. #include <boost/random/uniform_int.hpp>
  30. #include <boost/random/uniform_smallint.hpp>
  31. #include <boost/random/discrete_distribution.hpp>
  32. #include <sstream>
  33. typedef boost::mpl::list <
  34. boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::uint1024_t >,
  35. boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::int1024_t >,
  36. boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::checked_uint1024_t >,
  37. boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::checked_int1024_t >,
  38. boost::random::independent_bits_engine<boost::random::mt19937, 30000, boost::multiprecision::cpp_int >,
  39. boost::random::discard_block_engine<boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::uint1024_t >, 20, 10>,
  40. boost::random::discard_block_engine<boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::int1024_t >, 20, 10>,
  41. boost::random::discard_block_engine<boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::checked_uint1024_t >, 20, 10>,
  42. boost::random::discard_block_engine<boost::random::independent_bits_engine<boost::random::mt19937, 1024, boost::multiprecision::checked_int1024_t >, 20, 10>,
  43. boost::random::discard_block_engine<boost::random::independent_bits_engine<boost::random::mt19937, 600, boost::multiprecision::cpp_int >, 20, 10>
  44. > engines;
  45. BOOST_AUTO_TEST_CASE_TEMPLATE(generator_test, engine_type, engines)
  46. {
  47. typedef typename engine_type::result_type test_type;
  48. engine_type gen;
  49. gen.seed();
  50. test_type a = gen.min();
  51. test_type b = gen.max();
  52. BOOST_CHECK(a < b);
  53. a = gen();
  54. //
  55. // This extracts 32-bit values for use in seeding other sequences,
  56. // not really applicable here, and not functional for signed types anyway.
  57. //gen.generate(&b, &b + 1);
  58. gen.discard(20);
  59. typename engine_type::base_type base(gen.base());
  60. boost::ignore_unused(base);
  61. std::stringstream ss;
  62. ss << gen;
  63. engine_type gen2;
  64. ss >> gen2;
  65. BOOST_CHECK(gen == gen2);
  66. gen2();
  67. BOOST_CHECK(gen != gen2);
  68. //
  69. // construction and seeding:
  70. //
  71. engine_type gen3(0);
  72. gen3.seed(2);
  73. }
  74. BOOST_AUTO_TEST_CASE(xor_combine_test)
  75. {
  76. //
  77. // As above but with a few things missing which don't work - for example we have no
  78. // way to drill down and get the seed-type of the underlying generator.
  79. //
  80. typedef boost::random::xor_combine_engine<boost::random::independent_bits_engine<boost::random::mt19937, 512, boost::multiprecision::uint1024_t >, 512, boost::random::independent_bits_engine<boost::random::mt19937, 512, boost::multiprecision::uint1024_t >, 10> engine_type;
  81. typedef engine_type::result_type test_type;
  82. engine_type gen;
  83. gen.seed();
  84. test_type a = gen.min();
  85. test_type b = gen.max();
  86. BOOST_CHECK(a < b);
  87. a = gen();
  88. #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
  89. gen.generate(&b, &b + 1);
  90. #endif
  91. gen.discard(20);
  92. //typename engine_type::base_type base(gen.base());
  93. std::stringstream ss;
  94. ss << gen;
  95. engine_type gen2;
  96. ss >> gen2;
  97. BOOST_CHECK(gen == gen2);
  98. gen2();
  99. BOOST_CHECK(gen != gen2);
  100. //
  101. // construction and seeding:
  102. //
  103. //engine_type gen3(0);
  104. //gen3.seed(2);
  105. }
  106. typedef boost::mpl::list <
  107. boost::random::random_number_generator<boost::random::mt19937, boost::multiprecision::cpp_int>,
  108. boost::random::random_number_generator<boost::random::mt19937, boost::multiprecision::uint1024_t>,
  109. boost::random::random_number_generator<boost::random::mt19937, boost::multiprecision::checked_uint1024_t>
  110. > generators;
  111. BOOST_AUTO_TEST_CASE_TEMPLATE(random_number_generator, generator_type, generators)
  112. {
  113. typedef typename generator_type::result_type result_type;
  114. typedef typename generator_type::base_type base_type;
  115. result_type lim = 1;
  116. lim <<= 500;
  117. base_type base;
  118. generator_type gen(base);
  119. for(unsigned i = 0; i < 100; ++i)
  120. BOOST_CHECK(gen(lim) < lim);
  121. }
  122. typedef boost::mpl::list <
  123. boost::random::uniform_int_distribution<boost::multiprecision::cpp_int>,
  124. boost::random::uniform_int_distribution<boost::multiprecision::uint1024_t>,
  125. boost::random::uniform_int_distribution<boost::multiprecision::checked_uint1024_t>,
  126. boost::random::uniform_smallint<boost::multiprecision::cpp_int>,
  127. boost::random::uniform_smallint<boost::multiprecision::uint1024_t>,
  128. boost::random::uniform_smallint<boost::multiprecision::checked_uint1024_t>
  129. > uniform_distributions;
  130. BOOST_AUTO_TEST_CASE_TEMPLATE(distributions, distribution_type, uniform_distributions)
  131. {
  132. typedef typename distribution_type::result_type result_type;
  133. result_type a = 20;
  134. result_type b = 1;
  135. b <<= 1000;
  136. distribution_type d(a, b);
  137. boost::random::mt19937 gen;
  138. BOOST_CHECK_EQUAL(d.a(), a);
  139. BOOST_CHECK_EQUAL(d.b(), b);
  140. BOOST_CHECK_EQUAL((d.min)(), a);
  141. BOOST_CHECK_EQUAL((d.max)(), b);
  142. for(unsigned i = 0; i < 200; ++i)
  143. {
  144. result_type r = d(gen);
  145. BOOST_CHECK(r <= b);
  146. BOOST_CHECK(r >= a);
  147. }
  148. std::stringstream ss;
  149. ss << d;
  150. distribution_type d2;
  151. ss >> d2;
  152. BOOST_CHECK(d == d2);
  153. boost::random::independent_bits_engine<boost::random::mt19937, std::numeric_limits<boost::multiprecision::uint1024_t>::digits, boost::multiprecision::uint1024_t > big_random;
  154. for(unsigned i = 0; i < 200; ++i)
  155. {
  156. result_type r = d(big_random);
  157. BOOST_CHECK(r <= b);
  158. BOOST_CHECK(r >= a);
  159. }
  160. }
  161. #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
  162. typedef boost::mpl::list <
  163. boost::random::discrete_distribution < boost::multiprecision::cpp_int, double>,
  164. boost::random::discrete_distribution <unsigned int, boost::multiprecision::cpp_bin_float_100>
  165. > other_distributions;
  166. BOOST_AUTO_TEST_CASE_TEMPLATE(discrete_distributions, distribution_type, other_distributions)
  167. {
  168. typedef typename distribution_type::result_type result_type;
  169. typedef typename distribution_type::input_type input_type;
  170. input_type a[] = { 20, 30, 40, 50 };
  171. distribution_type d(a, a + 4);
  172. boost::random::mt19937 gen;
  173. for(unsigned i = 0; i < 200; ++i)
  174. {
  175. result_type r = d(gen);
  176. }
  177. std::stringstream ss;
  178. ss << std::setprecision(std::numeric_limits<input_type>::digits10 + 3) << d;
  179. distribution_type d2;
  180. ss >> d2;
  181. BOOST_CHECK(d == d2);
  182. boost::random::independent_bits_engine<boost::random::mt19937, std::numeric_limits<boost::multiprecision::uint1024_t>::digits, boost::multiprecision::uint1024_t > big_random;
  183. for(unsigned i = 0; i < 200; ++i)
  184. {
  185. result_type r = d(big_random);
  186. }
  187. }
  188. #endif