charconv_bigint_test.cc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // Copyright 2018 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "absl/strings/internal/charconv_bigint.h"
  15. #include <string>
  16. #include "gtest/gtest.h"
  17. namespace absl {
  18. ABSL_NAMESPACE_BEGIN
  19. namespace strings_internal {
  20. TEST(BigUnsigned, ShiftLeft) {
  21. {
  22. // Check that 3 * 2**100 is calculated correctly
  23. BigUnsigned<4> num(3u);
  24. num.ShiftLeft(100);
  25. EXPECT_EQ(num, BigUnsigned<4>("3802951800684688204490109616128"));
  26. }
  27. {
  28. // Test that overflow is truncated properly.
  29. // 15 is 4 bits long, and BigUnsigned<4> is a 128-bit bigint.
  30. // Shifting left by 125 bits should truncate off the high bit, so that
  31. // 15 << 125 == 7 << 125
  32. // after truncation.
  33. BigUnsigned<4> a(15u);
  34. BigUnsigned<4> b(7u);
  35. BigUnsigned<4> c(3u);
  36. a.ShiftLeft(125);
  37. b.ShiftLeft(125);
  38. c.ShiftLeft(125);
  39. EXPECT_EQ(a, b);
  40. EXPECT_NE(a, c);
  41. }
  42. {
  43. // Same test, larger bigint:
  44. BigUnsigned<84> a(15u);
  45. BigUnsigned<84> b(7u);
  46. BigUnsigned<84> c(3u);
  47. a.ShiftLeft(84 * 32 - 3);
  48. b.ShiftLeft(84 * 32 - 3);
  49. c.ShiftLeft(84 * 32 - 3);
  50. EXPECT_EQ(a, b);
  51. EXPECT_NE(a, c);
  52. }
  53. {
  54. // Check that incrementally shifting has the same result as doing it all at
  55. // once (attempting to capture corner cases.)
  56. const std::string seed = "1234567890123456789012345678901234567890";
  57. BigUnsigned<84> a(seed);
  58. for (int i = 1; i <= 84 * 32; ++i) {
  59. a.ShiftLeft(1);
  60. BigUnsigned<84> b(seed);
  61. b.ShiftLeft(i);
  62. EXPECT_EQ(a, b);
  63. }
  64. // And we should have fully rotated all bits off by now:
  65. EXPECT_EQ(a, BigUnsigned<84>(0u));
  66. }
  67. {
  68. // Bit shifting large and small numbers by large and small offsets.
  69. // Intended to exercise bounds-checking corner on ShiftLeft() (directly
  70. // and under asan).
  71. // 2**(32*84)-1
  72. const BigUnsigned<84> all_bits_one(
  73. "1474444211396924248063325089479706787923460402125687709454567433186613"
  74. "6228083464060749874845919674257665016359189106695900028098437021384227"
  75. "3285029708032466536084583113729486015826557532750465299832071590813090"
  76. "2011853039837649252477307070509704043541368002938784757296893793903797"
  77. "8180292336310543540677175225040919704702800559606097685920595947397024"
  78. "8303316808753252115729411497720357971050627997031988036134171378490368"
  79. "6008000778741115399296162550786288457245180872759047016734959330367829"
  80. "5235612397427686310674725251378116268607113017720538636924549612987647"
  81. "5767411074510311386444547332882472126067840027882117834454260409440463"
  82. "9345147252664893456053258463203120637089916304618696601333953616715125"
  83. "2115882482473279040772264257431663818610405673876655957323083702713344"
  84. "4201105427930770976052393421467136557055");
  85. const BigUnsigned<84> zero(0u);
  86. const BigUnsigned<84> one(1u);
  87. // in bounds shifts
  88. for (int i = 1; i < 84*32; ++i) {
  89. // shifting all_bits_one to the left should result in a smaller number,
  90. // since the high bits rotate off and the low bits are replaced with
  91. // zeroes.
  92. BigUnsigned<84> big_shifted = all_bits_one;
  93. big_shifted.ShiftLeft(i);
  94. EXPECT_GT(all_bits_one, big_shifted);
  95. // Shifting 1 to the left should instead result in a larger number.
  96. BigUnsigned<84> small_shifted = one;
  97. small_shifted.ShiftLeft(i);
  98. EXPECT_LT(one, small_shifted);
  99. }
  100. // Shifting by zero or a negative number has no effect
  101. for (int no_op_shift : {0, -1, -84 * 32, std::numeric_limits<int>::min()}) {
  102. BigUnsigned<84> big_shifted = all_bits_one;
  103. big_shifted.ShiftLeft(no_op_shift);
  104. EXPECT_EQ(all_bits_one, big_shifted);
  105. BigUnsigned<84> small_shifted = one;
  106. big_shifted.ShiftLeft(no_op_shift);
  107. EXPECT_EQ(one, small_shifted);
  108. }
  109. // Shifting by an amount greater than the number of bits should result in
  110. // zero.
  111. for (int out_of_bounds_shift :
  112. {84 * 32, 84 * 32 + 1, std::numeric_limits<int>::max()}) {
  113. BigUnsigned<84> big_shifted = all_bits_one;
  114. big_shifted.ShiftLeft(out_of_bounds_shift);
  115. EXPECT_EQ(zero, big_shifted);
  116. BigUnsigned<84> small_shifted = one;
  117. small_shifted.ShiftLeft(out_of_bounds_shift);
  118. EXPECT_EQ(zero, small_shifted);
  119. }
  120. }
  121. }
  122. TEST(BigUnsigned, MultiplyByUint32) {
  123. const BigUnsigned<84> factorial_100(
  124. "933262154439441526816992388562667004907159682643816214685929638952175999"
  125. "932299156089414639761565182862536979208272237582511852109168640000000000"
  126. "00000000000000");
  127. BigUnsigned<84> a(1u);
  128. for (uint32_t i = 1; i <= 100; ++i) {
  129. a.MultiplyBy(i);
  130. }
  131. EXPECT_EQ(a, BigUnsigned<84>(factorial_100));
  132. }
  133. TEST(BigUnsigned, MultiplyByBigUnsigned) {
  134. {
  135. // Put the terms of factorial_200 into two bigints, and multiply them
  136. // together.
  137. const BigUnsigned<84> factorial_200(
  138. "7886578673647905035523632139321850622951359776871732632947425332443594"
  139. "4996340334292030428401198462390417721213891963883025764279024263710506"
  140. "1926624952829931113462857270763317237396988943922445621451664240254033"
  141. "2918641312274282948532775242424075739032403212574055795686602260319041"
  142. "7032406235170085879617892222278962370389737472000000000000000000000000"
  143. "0000000000000000000000000");
  144. BigUnsigned<84> evens(1u);
  145. BigUnsigned<84> odds(1u);
  146. for (uint32_t i = 1; i < 200; i += 2) {
  147. odds.MultiplyBy(i);
  148. evens.MultiplyBy(i + 1);
  149. }
  150. evens.MultiplyBy(odds);
  151. EXPECT_EQ(evens, factorial_200);
  152. }
  153. {
  154. // Multiply various powers of 10 together.
  155. for (int a = 0 ; a < 700; a += 25) {
  156. SCOPED_TRACE(a);
  157. BigUnsigned<84> a_value("3" + std::string(a, '0'));
  158. for (int b = 0; b < (700 - a); b += 25) {
  159. SCOPED_TRACE(b);
  160. BigUnsigned<84> b_value("2" + std::string(b, '0'));
  161. BigUnsigned<84> expected_product("6" + std::string(a + b, '0'));
  162. b_value.MultiplyBy(a_value);
  163. EXPECT_EQ(b_value, expected_product);
  164. }
  165. }
  166. }
  167. }
  168. TEST(BigUnsigned, MultiplyByOverflow) {
  169. {
  170. // Check that multiplcation overflow predictably truncates.
  171. // A big int with all bits on.
  172. BigUnsigned<4> all_bits_on("340282366920938463463374607431768211455");
  173. // Modulo 2**128, this is equal to -1. Therefore the square of this,
  174. // modulo 2**128, should be 1.
  175. all_bits_on.MultiplyBy(all_bits_on);
  176. EXPECT_EQ(all_bits_on, BigUnsigned<4>(1u));
  177. }
  178. {
  179. // Try multiplying a large bigint by 2**50, and compare the result to
  180. // shifting.
  181. BigUnsigned<4> value_1("12345678901234567890123456789012345678");
  182. BigUnsigned<4> value_2("12345678901234567890123456789012345678");
  183. BigUnsigned<4> two_to_fiftieth(1u);
  184. two_to_fiftieth.ShiftLeft(50);
  185. value_1.ShiftLeft(50);
  186. value_2.MultiplyBy(two_to_fiftieth);
  187. EXPECT_EQ(value_1, value_2);
  188. }
  189. }
  190. TEST(BigUnsigned, FiveToTheNth) {
  191. {
  192. // Sanity check that MultiplyByFiveToTheNth gives consistent answers, up to
  193. // and including overflow.
  194. for (int i = 0; i < 1160; ++i) {
  195. SCOPED_TRACE(i);
  196. BigUnsigned<84> value_1(123u);
  197. BigUnsigned<84> value_2(123u);
  198. value_1.MultiplyByFiveToTheNth(i);
  199. for (int j = 0; j < i; j++) {
  200. value_2.MultiplyBy(5u);
  201. }
  202. EXPECT_EQ(value_1, value_2);
  203. }
  204. }
  205. {
  206. // Check that the faster, table-lookup-based static method returns the same
  207. // result that multiplying in-place would return, up to and including
  208. // overflow.
  209. for (int i = 0; i < 1160; ++i) {
  210. SCOPED_TRACE(i);
  211. BigUnsigned<84> value_1(1u);
  212. value_1.MultiplyByFiveToTheNth(i);
  213. BigUnsigned<84> value_2 = BigUnsigned<84>::FiveToTheNth(i);
  214. EXPECT_EQ(value_1, value_2);
  215. }
  216. }
  217. }
  218. TEST(BigUnsigned, TenToTheNth) {
  219. {
  220. // Sanity check MultiplyByTenToTheNth.
  221. for (int i = 0; i < 800; ++i) {
  222. SCOPED_TRACE(i);
  223. BigUnsigned<84> value_1(123u);
  224. BigUnsigned<84> value_2(123u);
  225. value_1.MultiplyByTenToTheNth(i);
  226. for (int j = 0; j < i; j++) {
  227. value_2.MultiplyBy(10u);
  228. }
  229. EXPECT_EQ(value_1, value_2);
  230. }
  231. }
  232. {
  233. // Alternate testing approach, taking advantage of the decimal parser.
  234. for (int i = 0; i < 200; ++i) {
  235. SCOPED_TRACE(i);
  236. BigUnsigned<84> value_1(135u);
  237. value_1.MultiplyByTenToTheNth(i);
  238. BigUnsigned<84> value_2("135" + std::string(i, '0'));
  239. EXPECT_EQ(value_1, value_2);
  240. }
  241. }
  242. }
  243. } // namespace strings_internal
  244. ABSL_NAMESPACE_END
  245. } // namespace absl