test_const_mod.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /* test_const_mod.cpp
  2. *
  3. * Copyright Steven Watanabe 2011
  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. */
  11. #include <boost/random/detail/const_mod.hpp>
  12. #include <boost/cstdint.hpp>
  13. #include <boost/mpl/vector.hpp>
  14. #define BOOST_TEST_MAIN
  15. #include <boost/test/unit_test.hpp>
  16. typedef boost::mpl::vector<
  17. boost::int8_t,
  18. boost::uint8_t
  19. > int8_types;
  20. BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult8, IntType, int8_types) {
  21. for(int i = 0; i < 127; ++i) {
  22. for(int j = 0; j < 127; ++j) {
  23. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 127>::mult(IntType(i), IntType(j))), i * j % 127);
  24. }
  25. }
  26. int modulus = (std::numeric_limits<IntType>::max)() + 1;
  27. for(int i = 0; i < modulus; ++i) {
  28. for(int j = 0; j < modulus; ++j) {
  29. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 0>::mult(IntType(i), IntType(j))), i * j % modulus);
  30. }
  31. }
  32. }
  33. BOOST_AUTO_TEST_CASE_TEMPLATE(test_add8, IntType, int8_types) {
  34. for(int i = 0; i < 127; ++i) {
  35. for(int j = 0; j < 127; ++j) {
  36. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 127>::add(IntType(i), IntType(j))), (i + j) % 127);
  37. }
  38. }
  39. {
  40. const int modulus = boost::integer_traits<IntType>::const_max;
  41. for(int i = 0; i < modulus; ++i) {
  42. for(int j = 0; j < modulus; ++j) {
  43. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, modulus>::add(IntType(i), IntType(j))), (i + j) % modulus);
  44. }
  45. }
  46. }
  47. {
  48. int modulus = (std::numeric_limits<IntType>::max)() + 1;
  49. for(int i = 0; i < modulus; ++i) {
  50. for(int j = 0; j < modulus; ++j) {
  51. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 0>::add(IntType(i), IntType(j))), (i + j) % modulus);
  52. }
  53. }
  54. }
  55. }
  56. BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult_add8, IntType, int8_types) {
  57. for(int i = 0; i < 127; i += 5) {
  58. for(int j = 0; j < 127; j += 3) {
  59. for(int k = 0; k < 127; k += 3) {
  60. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 127>::mult_add(IntType(i), IntType(j), IntType(k))), (i * j + k) % 127);
  61. }
  62. }
  63. }
  64. {
  65. int modulus = (std::numeric_limits<IntType>::max)() + 1;
  66. for(int i = 0; i < modulus; i += 5) {
  67. for(int j = 0; j < modulus; j += 3) {
  68. for(int k = 0; k < modulus; k += 3) {
  69. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 0>::mult_add(IntType(i), IntType(j), IntType(k))), (i * j + k) % modulus);
  70. }
  71. }
  72. }
  73. }
  74. }
  75. BOOST_AUTO_TEST_CASE_TEMPLATE(test_invert8, IntType, int8_types) {
  76. for(int i = 1; i < 127; ++i) {
  77. IntType inverse = boost::random::const_mod<IntType, 127>::invert(IntType(i));
  78. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 127>::mult(IntType(i), inverse)), 1);
  79. }
  80. int modulus = (std::numeric_limits<IntType>::max)() + 1;
  81. for(int i = 1; i < modulus; i += 2) {
  82. IntType inverse = boost::random::const_mod<IntType, 0>::invert(IntType(i));
  83. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 0>::mult(IntType(i), inverse)), 1);
  84. }
  85. }
  86. typedef boost::mpl::vector<
  87. boost::int32_t,
  88. boost::uint32_t
  89. > int32_types;
  90. BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult32, IntType, int32_types) {
  91. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(0, 0)), IntType(0));
  92. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(0, 2147483562)), IntType(0));
  93. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(2147483562, 0)), IntType(0));
  94. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(2147483562, 2147483562)), IntType(1));
  95. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(1234567890, 1234657890)), IntType(813106682));
  96. }
  97. BOOST_AUTO_TEST_CASE_TEMPLATE(test_add32, IntType, int32_types) {
  98. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(0, 0)), IntType(0));
  99. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(0, 2147483562)), IntType(2147483562));
  100. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(2147483562, 0)), IntType(2147483562));
  101. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(2147483562, 2147483562)), IntType(2147483561));
  102. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::add(1234567890, 1234657890)), IntType(321742217));
  103. }
  104. BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult_add32, IntType, int32_types) {
  105. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(0, 0, 0)), IntType(0));
  106. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(0, 2147483562, 827364)), IntType(827364));
  107. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(2147483562, 0, 827364)), IntType(827364));
  108. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(2147483562, 2147483562, 2147483562)), IntType(0));
  109. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(1234567890, 1234657890, 1726384759)), IntType(392007878));
  110. }
  111. BOOST_AUTO_TEST_CASE_TEMPLATE(test_invert32, IntType, int32_types) {
  112. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::invert(0)), IntType(0));
  113. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult_add(0, 0, 0)), IntType(0));
  114. IntType inverse;
  115. inverse = boost::random::const_mod<IntType, 2147483563>::invert(2147483562);
  116. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(2147483562, inverse)), IntType(1));
  117. inverse = boost::random::const_mod<IntType, 2147483563>::invert(1234567890);
  118. BOOST_CHECK_EQUAL((boost::random::const_mod<IntType, 2147483563>::mult(1234567890, inverse)), IntType(1));
  119. }
  120. #if !defined(BOOST_NO_INT64_T)
  121. typedef boost::mpl::vector<
  122. boost::int64_t,
  123. boost::uint64_t
  124. > int64_types;
  125. BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult64, IntType, int64_types) {
  126. typedef boost::random::const_mod<IntType, INT64_C(2147483563652738498)> const_mod_type;
  127. BOOST_CHECK_EQUAL((const_mod_type::mult(0, 0)), IntType(0));
  128. BOOST_CHECK_EQUAL((const_mod_type::mult(0, 2147483562)), IntType(0));
  129. BOOST_CHECK_EQUAL((const_mod_type::mult(2147483562, 0)), IntType(0));
  130. BOOST_CHECK_EQUAL((const_mod_type::mult(2147483562, 2147483562)), IntType(INT64_C(316718521754730848)));
  131. BOOST_CHECK_EQUAL((const_mod_type::mult(1234567890, 1234657890)), IntType(INT64_C(1524268986129152100)));
  132. BOOST_CHECK_EQUAL((const_mod_type::mult(INT64_C(1234567890726352938), INT64_C(1234657890736453927))), IntType(INT64_C(88656187017794672)));
  133. }
  134. BOOST_AUTO_TEST_CASE_TEMPLATE(test_add64, IntType, int64_types) {
  135. typedef boost::random::const_mod<IntType, INT64_C(2147483563652738498)> const_mod_type;
  136. BOOST_CHECK_EQUAL((const_mod_type::add(0, 0)), IntType(0));
  137. BOOST_CHECK_EQUAL((const_mod_type::add(0, 2147483562)), IntType(2147483562));
  138. BOOST_CHECK_EQUAL((const_mod_type::add(2147483562, 0)), IntType(2147483562));
  139. BOOST_CHECK_EQUAL((const_mod_type::add(2147483562, 2147483562)), IntType(4294967124U));
  140. BOOST_CHECK_EQUAL((const_mod_type::add(1234567890, 1234657890)), IntType(2469225780U));
  141. BOOST_CHECK_EQUAL((const_mod_type::add(INT64_C(1234567890726352938), INT64_C(1234657890736453927))), IntType(INT64_C(321742217810068367)));
  142. BOOST_CHECK_EQUAL((const_mod_type::add(INT64_C(2147483563652738490), 8)), IntType(0));
  143. }
  144. BOOST_AUTO_TEST_CASE_TEMPLATE(test_mult_add64, IntType, int64_types) {
  145. typedef boost::random::const_mod<IntType, INT64_C(2147483563652738498)> const_mod_type;
  146. BOOST_CHECK_EQUAL((const_mod_type::mult_add(0, 0, 0)), IntType(0));
  147. BOOST_CHECK_EQUAL((const_mod_type::mult_add(0, 2147483562, 827364)), IntType(827364));
  148. BOOST_CHECK_EQUAL((const_mod_type::mult_add(2147483562, 0, 827364)), IntType(827364));
  149. BOOST_CHECK_EQUAL((const_mod_type::mult_add(2147483562, 2147483562, 2147483562)), IntType(INT64_C(316718523902214410)));
  150. BOOST_CHECK_EQUAL((const_mod_type::mult_add(1234567890, 1234657890, 1726384759)), IntType(INT64_C(1524268987855536859)));
  151. BOOST_CHECK_EQUAL((const_mod_type::mult_add(INT64_C(1234567890726352938), INT64_C(1234657890736453927), INT64_C(1726384759726488649))), IntType(INT64_C(1815040946744283321)));
  152. }
  153. BOOST_AUTO_TEST_CASE_TEMPLATE(test_invert64, IntType, int64_types) {
  154. typedef boost::random::const_mod<IntType, INT64_C(2147483563652738498)> const_mod_type;
  155. BOOST_CHECK_EQUAL((const_mod_type::invert(0)), IntType(0));
  156. BOOST_CHECK_EQUAL((const_mod_type::mult_add(0, 0, 0)), IntType(0));
  157. IntType inverse;
  158. inverse = const_mod_type::invert(INT64_C(7362947769));
  159. BOOST_CHECK_EQUAL((const_mod_type::mult(INT64_C(7362947769), inverse)), IntType(1));
  160. inverse = const_mod_type::invert(INT64_C(1263142436887493875));
  161. BOOST_CHECK_EQUAL((const_mod_type::mult(INT64_C(1263142436887493875), inverse)), IntType(1));
  162. }
  163. #endif