ui128_division_ut.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #include <library/cpp/testing/unittest/registar.h>
  2. #include <library/cpp/int128/int128.h>
  3. #include <util/generic/cast.h>
  4. Y_UNIT_TEST_SUITE(Ui128DivisionBy1Suite) {
  5. Y_UNIT_TEST(Ui128Divide0By1) {
  6. ui128 dividend = 0;
  7. ui128 divider = 1;
  8. ui128 expectedQuotient = 0;
  9. ui128 expectedRemainder = 0;
  10. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  11. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  12. }
  13. Y_UNIT_TEST(Ui128Divide1By1) {
  14. ui128 dividend = 1;
  15. ui128 divider = 1;
  16. ui128 expectedQuotient = 1;
  17. ui128 expectedRemainder = 0;
  18. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  19. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  20. }
  21. Y_UNIT_TEST(Ui128Divide2By1) {
  22. ui128 dividend = 2;
  23. ui128 divider = 1;
  24. ui128 expectedQuotient = 2;
  25. ui128 expectedRemainder = 0;
  26. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  27. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  28. }
  29. Y_UNIT_TEST(Ui128Divide42By1) {
  30. ui128 dividend = 42;
  31. ui128 divider = 1;
  32. ui128 expectedQuotient = 42;
  33. ui128 expectedRemainder = 0;
  34. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  35. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  36. }
  37. Y_UNIT_TEST(Ui128DivideMaxUi64By1) {
  38. ui128 dividend = std::numeric_limits<ui64>::max();
  39. ui128 divider = 1;
  40. ui128 expectedQuotient = std::numeric_limits<ui64>::max();
  41. ui128 expectedRemainder = 0;
  42. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  43. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  44. }
  45. Y_UNIT_TEST(Ui128DivideMaxUi64Plus1By1) {
  46. ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
  47. ui128 divider = 1;
  48. ui128 expectedQuotient = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
  49. ui128 expectedRemainder = 0;
  50. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  51. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  52. }
  53. Y_UNIT_TEST(Ui128DivideMaxUi64Plus42By1) {
  54. ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{42};
  55. ui128 divider = 1;
  56. ui128 expectedQuotient = ui128{std::numeric_limits<ui64>::max()} + ui128{42};
  57. ui128 expectedRemainder = 0;
  58. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  59. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  60. }
  61. Y_UNIT_TEST(Ui128DivideMaxUi128By1) {
  62. ui128 dividend = std::numeric_limits<ui128>::max();
  63. ui128 divider = 1;
  64. ui128 expectedQuotient = std::numeric_limits<ui128>::max();
  65. ui128 expectedRemainder = 0;
  66. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  67. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  68. }
  69. Y_UNIT_TEST(Ui128DivideMaxUi128Minus1By1) {
  70. ui128 dividend = std::numeric_limits<ui128>::max() - 1;
  71. ui128 divider = 1;
  72. ui128 expectedQuotient = std::numeric_limits<ui128>::max() - 1;
  73. ui128 expectedRemainder = 0;
  74. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  75. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  76. }
  77. }
  78. Y_UNIT_TEST_SUITE(Ui128DivisionByEqualSuite) {
  79. Y_UNIT_TEST(Ui128Divide1ByEqual) {
  80. ui128 dividend = 1;
  81. ui128 divider = dividend;
  82. ui128 expectedQuotient = 1;
  83. ui128 expectedRemainder = 0;
  84. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  85. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  86. }
  87. Y_UNIT_TEST(Ui128Divide2ByEqual) {
  88. ui128 dividend = 2;
  89. ui128 divider = dividend;
  90. ui128 expectedQuotient = 1;
  91. ui128 expectedRemainder = 0;
  92. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  93. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  94. }
  95. Y_UNIT_TEST(Ui128Divide42ByEqual) {
  96. ui128 dividend = 42;
  97. ui128 divider = dividend;
  98. ui128 expectedQuotient = 1;
  99. ui128 expectedRemainder = 0;
  100. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  101. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  102. }
  103. Y_UNIT_TEST(Ui128DivideMaxUi64ByEqual) {
  104. ui128 dividend = std::numeric_limits<ui64>::max();
  105. ui128 divider = dividend;
  106. ui128 expectedQuotient = 1;
  107. ui128 expectedRemainder = 0;
  108. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  109. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  110. }
  111. Y_UNIT_TEST(Ui128DivideMaxUi64Plus1ByEqual) {
  112. ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
  113. ui128 divider = dividend;
  114. ui128 expectedQuotient = 1;
  115. ui128 expectedRemainder = 0;
  116. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  117. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  118. }
  119. Y_UNIT_TEST(Ui128DivideMaxUi64Plus42ByEqual) {
  120. ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{42};
  121. ui128 divider = dividend;
  122. ui128 expectedQuotient = 1;
  123. ui128 expectedRemainder = 0;
  124. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  125. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  126. }
  127. Y_UNIT_TEST(Ui128DivideMaxUi128ByEqual) {
  128. ui128 dividend = std::numeric_limits<ui128>::max();
  129. ui128 divider = dividend;
  130. ui128 expectedQuotient = 1;
  131. ui128 expectedRemainder = 0;
  132. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  133. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  134. }
  135. Y_UNIT_TEST(Ui128DivideMaxUi128Minus1ByEqual) {
  136. ui128 dividend = std::numeric_limits<ui128>::max() - 1;
  137. ui128 divider = dividend;
  138. ui128 expectedQuotient = 1;
  139. ui128 expectedRemainder = 0;
  140. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  141. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  142. }
  143. }
  144. Y_UNIT_TEST_SUITE(Ui128DivisionLessByHigherSuite) {
  145. Y_UNIT_TEST(Ui128Divide42By84) {
  146. ui128 dividend = 42;
  147. ui128 divider = 84;
  148. ui128 expectedQuotient = 0;
  149. ui128 expectedRemainder = 42;
  150. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  151. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  152. }
  153. Y_UNIT_TEST(Ui128Divide42ByMaxUi64) {
  154. ui128 dividend = 42;
  155. ui128 divider = std::numeric_limits<ui64>::max();
  156. ui128 expectedQuotient = 0;
  157. ui128 expectedRemainder = 42;
  158. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  159. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  160. }
  161. Y_UNIT_TEST(Ui128Divide42ByMaxUi64Plus1) {
  162. ui128 dividend = 42;
  163. ui128 divider = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
  164. ui128 expectedQuotient = 0;
  165. ui128 expectedRemainder = 42;
  166. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  167. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  168. }
  169. Y_UNIT_TEST(Ui128DivideMaxUi64ByMaxUi64Plus1) {
  170. ui128 dividend = ui128{std::numeric_limits<ui64>::max()};
  171. ui128 divider = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
  172. ui128 expectedQuotient = 0;
  173. ui128 expectedRemainder = ui128{std::numeric_limits<ui64>::max()};
  174. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  175. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  176. }
  177. }
  178. Y_UNIT_TEST_SUITE(Ui128DivisionBigByBigSuite) {
  179. Y_UNIT_TEST(Ui128DivideBigByBig1) {
  180. ui128 dividend = {64, 0};
  181. ui128 divider = {1, 0};
  182. ui128 expectedQuotient = 64;
  183. ui128 expectedRemainder = 0;
  184. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  185. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  186. }
  187. Y_UNIT_TEST(Ui128DivideBigByBig2) {
  188. ui128 dividend = {64, 0};
  189. ui128 divider = {12, 5};
  190. ui128 expectedQuotient = 5;
  191. ui128 expectedRemainder = ui128{3, 18446744073709551591ull}; // plz don't ask
  192. UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
  193. UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
  194. }
  195. }
  196. Y_UNIT_TEST_SUITE(Ui128DivisionAlgo) {
  197. Y_UNIT_TEST(Ui128DivideAlgoCheck) {
  198. /*
  199. 49672666804009505000000 / 10000000 == 4967266680400950
  200. 49672666804009505000000 % 10000000 == 5000000
  201. */
  202. ui128 dividend = {2692ull, 14031757583392049728ull};
  203. ui64 divider = 10000000;
  204. ui128 expectedQuotient = {0, 4967266680400950ull};
  205. ui128 expectedRemainder = {0, 5000000ull};
  206. ui128 quotient = dividend / divider;
  207. ui128 reminder = dividend % divider;
  208. UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
  209. UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
  210. }
  211. }