abseil-cpp/absl/strings/internal/charconv_bigint_test.cc
Go to the documentation of this file.
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 
15 #include "absl/strings/internal/charconv_bigint.h"
16 
17 #include <string>
18 
19 #include "gtest/gtest.h"
20 
21 namespace absl {
23 namespace strings_internal {
24 
25 TEST(BigUnsigned, ShiftLeft) {
26  {
27  // Check that 3 * 2**100 is calculated correctly
29  num.ShiftLeft(100);
30  EXPECT_EQ(num, BigUnsigned<4>("3802951800684688204490109616128"));
31  }
32  {
33  // Test that overflow is truncated properly.
34  // 15 is 4 bits long, and BigUnsigned<4> is a 128-bit bigint.
35  // Shifting left by 125 bits should truncate off the high bit, so that
36  // 15 << 125 == 7 << 125
37  // after truncation.
38  BigUnsigned<4> a(15u);
39  BigUnsigned<4> b(7u);
40  BigUnsigned<4> c(3u);
41  a.ShiftLeft(125);
42  b.ShiftLeft(125);
43  c.ShiftLeft(125);
44  EXPECT_EQ(a, b);
45  EXPECT_NE(a, c);
46  }
47  {
48  // Same test, larger bigint:
49  BigUnsigned<84> a(15u);
51  BigUnsigned<84> c(3u);
52  a.ShiftLeft(84 * 32 - 3);
53  b.ShiftLeft(84 * 32 - 3);
54  c.ShiftLeft(84 * 32 - 3);
55  EXPECT_EQ(a, b);
56  EXPECT_NE(a, c);
57  }
58  {
59  // Check that incrementally shifting has the same result as doing it all at
60  // once (attempting to capture corner cases.)
61  const std::string seed = "1234567890123456789012345678901234567890";
63  for (int i = 1; i <= 84 * 32; ++i) {
64  a.ShiftLeft(1);
66  b.ShiftLeft(i);
67  EXPECT_EQ(a, b);
68  }
69  // And we should have fully rotated all bits off by now:
71  }
72  {
73  // Bit shifting large and small numbers by large and small offsets.
74  // Intended to exercise bounds-checking corner on ShiftLeft() (directly
75  // and under asan).
76 
77  // 2**(32*84)-1
78  const BigUnsigned<84> all_bits_one(
79  "1474444211396924248063325089479706787923460402125687709454567433186613"
80  "6228083464060749874845919674257665016359189106695900028098437021384227"
81  "3285029708032466536084583113729486015826557532750465299832071590813090"
82  "2011853039837649252477307070509704043541368002938784757296893793903797"
83  "8180292336310543540677175225040919704702800559606097685920595947397024"
84  "8303316808753252115729411497720357971050627997031988036134171378490368"
85  "6008000778741115399296162550786288457245180872759047016734959330367829"
86  "5235612397427686310674725251378116268607113017720538636924549612987647"
87  "5767411074510311386444547332882472126067840027882117834454260409440463"
88  "9345147252664893456053258463203120637089916304618696601333953616715125"
89  "2115882482473279040772264257431663818610405673876655957323083702713344"
90  "4201105427930770976052393421467136557055");
91  const BigUnsigned<84> zero(0u);
92  const BigUnsigned<84> one(1u);
93  // in bounds shifts
94  for (int i = 1; i < 84*32; ++i) {
95  // shifting all_bits_one to the left should result in a smaller number,
96  // since the high bits rotate off and the low bits are replaced with
97  // zeroes.
98  BigUnsigned<84> big_shifted = all_bits_one;
99  big_shifted.ShiftLeft(i);
100  EXPECT_GT(all_bits_one, big_shifted);
101  // Shifting 1 to the left should instead result in a larger number.
102  BigUnsigned<84> small_shifted = one;
103  small_shifted.ShiftLeft(i);
104  EXPECT_LT(one, small_shifted);
105  }
106  // Shifting by zero or a negative number has no effect
107  for (int no_op_shift : {0, -1, -84 * 32, std::numeric_limits<int>::min()}) {
108  BigUnsigned<84> big_shifted = all_bits_one;
109  big_shifted.ShiftLeft(no_op_shift);
110  EXPECT_EQ(all_bits_one, big_shifted);
111  BigUnsigned<84> small_shifted = one;
112  big_shifted.ShiftLeft(no_op_shift);
113  EXPECT_EQ(one, small_shifted);
114  }
115  // Shifting by an amount greater than the number of bits should result in
116  // zero.
117  for (int out_of_bounds_shift :
118  {84 * 32, 84 * 32 + 1, std::numeric_limits<int>::max()}) {
119  BigUnsigned<84> big_shifted = all_bits_one;
120  big_shifted.ShiftLeft(out_of_bounds_shift);
121  EXPECT_EQ(zero, big_shifted);
122  BigUnsigned<84> small_shifted = one;
123  small_shifted.ShiftLeft(out_of_bounds_shift);
124  EXPECT_EQ(zero, small_shifted);
125  }
126  }
127 }
128 
129 TEST(BigUnsigned, MultiplyByUint32) {
130  const BigUnsigned<84> factorial_100(
131  "933262154439441526816992388562667004907159682643816214685929638952175999"
132  "932299156089414639761565182862536979208272237582511852109168640000000000"
133  "00000000000000");
134  BigUnsigned<84> a(1u);
135  for (uint32_t i = 1; i <= 100; ++i) {
136  a.MultiplyBy(i);
137  }
138  EXPECT_EQ(a, BigUnsigned<84>(factorial_100));
139 }
140 
141 TEST(BigUnsigned, MultiplyByBigUnsigned) {
142  {
143  // Put the terms of factorial_200 into two bigints, and multiply them
144  // together.
145  const BigUnsigned<84> factorial_200(
146  "7886578673647905035523632139321850622951359776871732632947425332443594"
147  "4996340334292030428401198462390417721213891963883025764279024263710506"
148  "1926624952829931113462857270763317237396988943922445621451664240254033"
149  "2918641312274282948532775242424075739032403212574055795686602260319041"
150  "7032406235170085879617892222278962370389737472000000000000000000000000"
151  "0000000000000000000000000");
152  BigUnsigned<84> evens(1u);
153  BigUnsigned<84> odds(1u);
154  for (uint32_t i = 1; i < 200; i += 2) {
155  odds.MultiplyBy(i);
156  evens.MultiplyBy(i + 1);
157  }
158  evens.MultiplyBy(odds);
159  EXPECT_EQ(evens, factorial_200);
160  }
161  {
162  // Multiply various powers of 10 together.
163  for (int a = 0 ; a < 700; a += 25) {
164  SCOPED_TRACE(a);
165  BigUnsigned<84> a_value("3" + std::string(a, '0'));
166  for (int b = 0; b < (700 - a); b += 25) {
167  SCOPED_TRACE(b);
168  BigUnsigned<84> b_value("2" + std::string(b, '0'));
169  BigUnsigned<84> expected_product("6" + std::string(a + b, '0'));
170  b_value.MultiplyBy(a_value);
171  EXPECT_EQ(b_value, expected_product);
172  }
173  }
174  }
175 }
176 
177 TEST(BigUnsigned, MultiplyByOverflow) {
178  {
179  // Check that multiplcation overflow predictably truncates.
180 
181  // A big int with all bits on.
182  BigUnsigned<4> all_bits_on("340282366920938463463374607431768211455");
183  // Modulo 2**128, this is equal to -1. Therefore the square of this,
184  // modulo 2**128, should be 1.
185  all_bits_on.MultiplyBy(all_bits_on);
186  EXPECT_EQ(all_bits_on, BigUnsigned<4>(1u));
187  }
188  {
189  // Try multiplying a large bigint by 2**50, and compare the result to
190  // shifting.
191  BigUnsigned<4> value_1("12345678901234567890123456789012345678");
192  BigUnsigned<4> value_2("12345678901234567890123456789012345678");
193  BigUnsigned<4> two_to_fiftieth(1u);
194  two_to_fiftieth.ShiftLeft(50);
195 
196  value_1.ShiftLeft(50);
197  value_2.MultiplyBy(two_to_fiftieth);
198  EXPECT_EQ(value_1, value_2);
199  }
200 }
201 
202 TEST(BigUnsigned, FiveToTheNth) {
203  {
204  // Sanity check that MultiplyByFiveToTheNth gives consistent answers, up to
205  // and including overflow.
206  for (int i = 0; i < 1160; ++i) {
207  SCOPED_TRACE(i);
208  BigUnsigned<84> value_1(123u);
209  BigUnsigned<84> value_2(123u);
210  value_1.MultiplyByFiveToTheNth(i);
211  for (int j = 0; j < i; j++) {
212  value_2.MultiplyBy(5u);
213  }
214  EXPECT_EQ(value_1, value_2);
215  }
216  }
217  {
218  // Check that the faster, table-lookup-based static method returns the same
219  // result that multiplying in-place would return, up to and including
220  // overflow.
221  for (int i = 0; i < 1160; ++i) {
222  SCOPED_TRACE(i);
223  BigUnsigned<84> value_1(1u);
224  value_1.MultiplyByFiveToTheNth(i);
226  EXPECT_EQ(value_1, value_2);
227  }
228  }
229 }
230 
231 TEST(BigUnsigned, TenToTheNth) {
232  {
233  // Sanity check MultiplyByTenToTheNth.
234  for (int i = 0; i < 800; ++i) {
235  SCOPED_TRACE(i);
236  BigUnsigned<84> value_1(123u);
237  BigUnsigned<84> value_2(123u);
238  value_1.MultiplyByTenToTheNth(i);
239  for (int j = 0; j < i; j++) {
240  value_2.MultiplyBy(10u);
241  }
242  EXPECT_EQ(value_1, value_2);
243  }
244  }
245  {
246  // Alternate testing approach, taking advantage of the decimal parser.
247  for (int i = 0; i < 200; ++i) {
248  SCOPED_TRACE(i);
249  BigUnsigned<84> value_1(135u);
250  value_1.MultiplyByTenToTheNth(i);
251  BigUnsigned<84> value_2("135" + std::string(i, '0'));
252  EXPECT_EQ(value_1, value_2);
253  }
254  }
255 }
256 
257 
258 } // namespace strings_internal
260 } // namespace absl
seed
static const uint8_t seed[20]
Definition: dsa_test.cc:79
EXPECT_GT
#define EXPECT_GT(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2036
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
absl::strings_internal::BigUnsigned::FiveToTheNth
static BigUnsigned FiveToTheNth(int n)
Definition: abseil-cpp/absl/strings/internal/charconv_bigint.cc:288
u
OPENSSL_EXPORT pem_password_cb void * u
Definition: pem.h:351
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
absl::strings_internal::BigUnsigned::MultiplyByTenToTheNth
void MultiplyByTenToTheNth(int n)
Definition: abseil-cpp/absl/strings/internal/charconv_bigint.h:175
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
SCOPED_TRACE
#define SCOPED_TRACE(message)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2264
absl::strings_internal::BigUnsigned
Definition: abseil-cpp/absl/strings/internal/charconv_bigint.h:57
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
absl::strings_internal::TEST
TEST(BigUnsigned, ShiftLeft)
Definition: abseil-cpp/absl/strings/internal/charconv_bigint_test.cc:25
min
#define min(a, b)
Definition: qsort.h:83
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
absl::strings_internal::BigUnsigned::MultiplyBy
void MultiplyBy(uint32_t v)
Definition: abseil-cpp/absl/strings/internal/charconv_bigint.h:130
absl::strings_internal::BigUnsigned::MultiplyByFiveToTheNth
void MultiplyByFiveToTheNth(int n)
Definition: abseil-cpp/absl/strings/internal/charconv_bigint.h:164
absl::strings_internal::BigUnsigned::ShiftLeft
void ShiftLeft(int count)
Definition: abseil-cpp/absl/strings/internal/charconv_bigint.h:102
EXPECT_LT
#define EXPECT_LT(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2032
xds_manager.num
num
Definition: xds_manager.py:56
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:53