1*9356374aSAndroid Build Coastguard Worker // Copyright 2018 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker
15*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_
16*9356374aSAndroid Build Coastguard Worker #define ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_
17*9356374aSAndroid Build Coastguard Worker
18*9356374aSAndroid Build Coastguard Worker #include <algorithm>
19*9356374aSAndroid Build Coastguard Worker #include <cstdint>
20*9356374aSAndroid Build Coastguard Worker #include <iostream>
21*9356374aSAndroid Build Coastguard Worker #include <string>
22*9356374aSAndroid Build Coastguard Worker
23*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h"
24*9356374aSAndroid Build Coastguard Worker #include "absl/strings/ascii.h"
25*9356374aSAndroid Build Coastguard Worker #include "absl/strings/internal/charconv_parse.h"
26*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
27*9356374aSAndroid Build Coastguard Worker
28*9356374aSAndroid Build Coastguard Worker namespace absl {
29*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
30*9356374aSAndroid Build Coastguard Worker namespace strings_internal {
31*9356374aSAndroid Build Coastguard Worker
32*9356374aSAndroid Build Coastguard Worker // The largest power that 5 that can be raised to, and still fit in a uint32_t.
33*9356374aSAndroid Build Coastguard Worker constexpr int kMaxSmallPowerOfFive = 13;
34*9356374aSAndroid Build Coastguard Worker // The largest power that 10 that can be raised to, and still fit in a uint32_t.
35*9356374aSAndroid Build Coastguard Worker constexpr int kMaxSmallPowerOfTen = 9;
36*9356374aSAndroid Build Coastguard Worker
37*9356374aSAndroid Build Coastguard Worker ABSL_DLL extern const uint32_t
38*9356374aSAndroid Build Coastguard Worker kFiveToNth[kMaxSmallPowerOfFive + 1];
39*9356374aSAndroid Build Coastguard Worker ABSL_DLL extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1];
40*9356374aSAndroid Build Coastguard Worker
41*9356374aSAndroid Build Coastguard Worker // Large, fixed-width unsigned integer.
42*9356374aSAndroid Build Coastguard Worker //
43*9356374aSAndroid Build Coastguard Worker // Exact rounding for decimal-to-binary floating point conversion requires very
44*9356374aSAndroid Build Coastguard Worker // large integer math, but a design goal of absl::from_chars is to avoid
45*9356374aSAndroid Build Coastguard Worker // allocating memory. The integer precision needed for decimal-to-binary
46*9356374aSAndroid Build Coastguard Worker // conversions is large but bounded, so a huge fixed-width integer class
47*9356374aSAndroid Build Coastguard Worker // suffices.
48*9356374aSAndroid Build Coastguard Worker //
49*9356374aSAndroid Build Coastguard Worker // This is an intentionally limited big integer class. Only needed operations
50*9356374aSAndroid Build Coastguard Worker // are implemented. All storage lives in an array data member, and all
51*9356374aSAndroid Build Coastguard Worker // arithmetic is done in-place, to avoid requiring separate storage for operand
52*9356374aSAndroid Build Coastguard Worker // and result.
53*9356374aSAndroid Build Coastguard Worker //
54*9356374aSAndroid Build Coastguard Worker // This is an internal class. Some methods live in the .cc file, and are
55*9356374aSAndroid Build Coastguard Worker // instantiated only for the values of max_words we need.
56*9356374aSAndroid Build Coastguard Worker template <int max_words>
57*9356374aSAndroid Build Coastguard Worker class BigUnsigned {
58*9356374aSAndroid Build Coastguard Worker public:
59*9356374aSAndroid Build Coastguard Worker static_assert(max_words == 4 || max_words == 84,
60*9356374aSAndroid Build Coastguard Worker "unsupported max_words value");
61*9356374aSAndroid Build Coastguard Worker
BigUnsigned()62*9356374aSAndroid Build Coastguard Worker BigUnsigned() : size_(0), words_{} {}
BigUnsigned(uint64_t v)63*9356374aSAndroid Build Coastguard Worker explicit constexpr BigUnsigned(uint64_t v)
64*9356374aSAndroid Build Coastguard Worker : size_((v >> 32) ? 2 : v ? 1 : 0),
65*9356374aSAndroid Build Coastguard Worker words_{static_cast<uint32_t>(v & 0xffffffffu),
66*9356374aSAndroid Build Coastguard Worker static_cast<uint32_t>(v >> 32)} {}
67*9356374aSAndroid Build Coastguard Worker
68*9356374aSAndroid Build Coastguard Worker // Constructs a BigUnsigned from the given string_view containing a decimal
69*9356374aSAndroid Build Coastguard Worker // value. If the input string is not a decimal integer, constructs a 0
70*9356374aSAndroid Build Coastguard Worker // instead.
BigUnsigned(absl::string_view sv)71*9356374aSAndroid Build Coastguard Worker explicit BigUnsigned(absl::string_view sv) : size_(0), words_{} {
72*9356374aSAndroid Build Coastguard Worker // Check for valid input, returning a 0 otherwise. This is reasonable
73*9356374aSAndroid Build Coastguard Worker // behavior only because this constructor is for unit tests.
74*9356374aSAndroid Build Coastguard Worker if (std::find_if_not(sv.begin(), sv.end(), ascii_isdigit) != sv.end() ||
75*9356374aSAndroid Build Coastguard Worker sv.empty()) {
76*9356374aSAndroid Build Coastguard Worker return;
77*9356374aSAndroid Build Coastguard Worker }
78*9356374aSAndroid Build Coastguard Worker int exponent_adjust =
79*9356374aSAndroid Build Coastguard Worker ReadDigits(sv.data(), sv.data() + sv.size(), Digits10() + 1);
80*9356374aSAndroid Build Coastguard Worker if (exponent_adjust > 0) {
81*9356374aSAndroid Build Coastguard Worker MultiplyByTenToTheNth(exponent_adjust);
82*9356374aSAndroid Build Coastguard Worker }
83*9356374aSAndroid Build Coastguard Worker }
84*9356374aSAndroid Build Coastguard Worker
85*9356374aSAndroid Build Coastguard Worker // Loads the mantissa value of a previously-parsed float.
86*9356374aSAndroid Build Coastguard Worker //
87*9356374aSAndroid Build Coastguard Worker // Returns the associated decimal exponent. The value of the parsed float is
88*9356374aSAndroid Build Coastguard Worker // exactly *this * 10**exponent.
89*9356374aSAndroid Build Coastguard Worker int ReadFloatMantissa(const ParsedFloat& fp, int significant_digits);
90*9356374aSAndroid Build Coastguard Worker
91*9356374aSAndroid Build Coastguard Worker // Returns the number of decimal digits of precision this type provides. All
92*9356374aSAndroid Build Coastguard Worker // numbers with this many decimal digits or fewer are representable by this
93*9356374aSAndroid Build Coastguard Worker // type.
94*9356374aSAndroid Build Coastguard Worker //
95*9356374aSAndroid Build Coastguard Worker // Analogous to std::numeric_limits<BigUnsigned>::digits10.
Digits10()96*9356374aSAndroid Build Coastguard Worker static constexpr int Digits10() {
97*9356374aSAndroid Build Coastguard Worker // 9975007/1035508 is very slightly less than log10(2**32).
98*9356374aSAndroid Build Coastguard Worker return static_cast<uint64_t>(max_words) * 9975007 / 1035508;
99*9356374aSAndroid Build Coastguard Worker }
100*9356374aSAndroid Build Coastguard Worker
101*9356374aSAndroid Build Coastguard Worker // Shifts left by the given number of bits.
ShiftLeft(int count)102*9356374aSAndroid Build Coastguard Worker void ShiftLeft(int count) {
103*9356374aSAndroid Build Coastguard Worker if (count > 0) {
104*9356374aSAndroid Build Coastguard Worker const int word_shift = count / 32;
105*9356374aSAndroid Build Coastguard Worker if (word_shift >= max_words) {
106*9356374aSAndroid Build Coastguard Worker SetToZero();
107*9356374aSAndroid Build Coastguard Worker return;
108*9356374aSAndroid Build Coastguard Worker }
109*9356374aSAndroid Build Coastguard Worker size_ = (std::min)(size_ + word_shift, max_words);
110*9356374aSAndroid Build Coastguard Worker count %= 32;
111*9356374aSAndroid Build Coastguard Worker if (count == 0) {
112*9356374aSAndroid Build Coastguard Worker // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=warray-bounds
113*9356374aSAndroid Build Coastguard Worker // shows a lot of bogus -Warray-bounds warnings under GCC.
114*9356374aSAndroid Build Coastguard Worker // This is not the only one in Abseil.
115*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(14, 0)
116*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic push
117*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Warray-bounds"
118*9356374aSAndroid Build Coastguard Worker #endif
119*9356374aSAndroid Build Coastguard Worker std::copy_backward(words_, words_ + size_ - word_shift, words_ + size_);
120*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(14, 0)
121*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic pop
122*9356374aSAndroid Build Coastguard Worker #endif
123*9356374aSAndroid Build Coastguard Worker } else {
124*9356374aSAndroid Build Coastguard Worker for (int i = (std::min)(size_, max_words - 1); i > word_shift; --i) {
125*9356374aSAndroid Build Coastguard Worker words_[i] = (words_[i - word_shift] << count) |
126*9356374aSAndroid Build Coastguard Worker (words_[i - word_shift - 1] >> (32 - count));
127*9356374aSAndroid Build Coastguard Worker }
128*9356374aSAndroid Build Coastguard Worker words_[word_shift] = words_[0] << count;
129*9356374aSAndroid Build Coastguard Worker // Grow size_ if necessary.
130*9356374aSAndroid Build Coastguard Worker if (size_ < max_words && words_[size_]) {
131*9356374aSAndroid Build Coastguard Worker ++size_;
132*9356374aSAndroid Build Coastguard Worker }
133*9356374aSAndroid Build Coastguard Worker }
134*9356374aSAndroid Build Coastguard Worker std::fill_n(words_, word_shift, 0u);
135*9356374aSAndroid Build Coastguard Worker }
136*9356374aSAndroid Build Coastguard Worker }
137*9356374aSAndroid Build Coastguard Worker
138*9356374aSAndroid Build Coastguard Worker
139*9356374aSAndroid Build Coastguard Worker // Multiplies by v in-place.
MultiplyBy(uint32_t v)140*9356374aSAndroid Build Coastguard Worker void MultiplyBy(uint32_t v) {
141*9356374aSAndroid Build Coastguard Worker if (size_ == 0 || v == 1) {
142*9356374aSAndroid Build Coastguard Worker return;
143*9356374aSAndroid Build Coastguard Worker }
144*9356374aSAndroid Build Coastguard Worker if (v == 0) {
145*9356374aSAndroid Build Coastguard Worker SetToZero();
146*9356374aSAndroid Build Coastguard Worker return;
147*9356374aSAndroid Build Coastguard Worker }
148*9356374aSAndroid Build Coastguard Worker const uint64_t factor = v;
149*9356374aSAndroid Build Coastguard Worker uint64_t window = 0;
150*9356374aSAndroid Build Coastguard Worker for (int i = 0; i < size_; ++i) {
151*9356374aSAndroid Build Coastguard Worker window += factor * words_[i];
152*9356374aSAndroid Build Coastguard Worker words_[i] = window & 0xffffffff;
153*9356374aSAndroid Build Coastguard Worker window >>= 32;
154*9356374aSAndroid Build Coastguard Worker }
155*9356374aSAndroid Build Coastguard Worker // If carry bits remain and there's space for them, grow size_.
156*9356374aSAndroid Build Coastguard Worker if (window && size_ < max_words) {
157*9356374aSAndroid Build Coastguard Worker words_[size_] = window & 0xffffffff;
158*9356374aSAndroid Build Coastguard Worker ++size_;
159*9356374aSAndroid Build Coastguard Worker }
160*9356374aSAndroid Build Coastguard Worker }
161*9356374aSAndroid Build Coastguard Worker
MultiplyBy(uint64_t v)162*9356374aSAndroid Build Coastguard Worker void MultiplyBy(uint64_t v) {
163*9356374aSAndroid Build Coastguard Worker uint32_t words[2];
164*9356374aSAndroid Build Coastguard Worker words[0] = static_cast<uint32_t>(v);
165*9356374aSAndroid Build Coastguard Worker words[1] = static_cast<uint32_t>(v >> 32);
166*9356374aSAndroid Build Coastguard Worker if (words[1] == 0) {
167*9356374aSAndroid Build Coastguard Worker MultiplyBy(words[0]);
168*9356374aSAndroid Build Coastguard Worker } else {
169*9356374aSAndroid Build Coastguard Worker MultiplyBy(2, words);
170*9356374aSAndroid Build Coastguard Worker }
171*9356374aSAndroid Build Coastguard Worker }
172*9356374aSAndroid Build Coastguard Worker
173*9356374aSAndroid Build Coastguard Worker // Multiplies in place by 5 to the power of n. n must be non-negative.
MultiplyByFiveToTheNth(int n)174*9356374aSAndroid Build Coastguard Worker void MultiplyByFiveToTheNth(int n) {
175*9356374aSAndroid Build Coastguard Worker while (n >= kMaxSmallPowerOfFive) {
176*9356374aSAndroid Build Coastguard Worker MultiplyBy(kFiveToNth[kMaxSmallPowerOfFive]);
177*9356374aSAndroid Build Coastguard Worker n -= kMaxSmallPowerOfFive;
178*9356374aSAndroid Build Coastguard Worker }
179*9356374aSAndroid Build Coastguard Worker if (n > 0) {
180*9356374aSAndroid Build Coastguard Worker MultiplyBy(kFiveToNth[n]);
181*9356374aSAndroid Build Coastguard Worker }
182*9356374aSAndroid Build Coastguard Worker }
183*9356374aSAndroid Build Coastguard Worker
184*9356374aSAndroid Build Coastguard Worker // Multiplies in place by 10 to the power of n. n must be non-negative.
MultiplyByTenToTheNth(int n)185*9356374aSAndroid Build Coastguard Worker void MultiplyByTenToTheNth(int n) {
186*9356374aSAndroid Build Coastguard Worker if (n > kMaxSmallPowerOfTen) {
187*9356374aSAndroid Build Coastguard Worker // For large n, raise to a power of 5, then shift left by the same amount.
188*9356374aSAndroid Build Coastguard Worker // (10**n == 5**n * 2**n.) This requires fewer multiplications overall.
189*9356374aSAndroid Build Coastguard Worker MultiplyByFiveToTheNth(n);
190*9356374aSAndroid Build Coastguard Worker ShiftLeft(n);
191*9356374aSAndroid Build Coastguard Worker } else if (n > 0) {
192*9356374aSAndroid Build Coastguard Worker // We can do this more quickly for very small N by using a single
193*9356374aSAndroid Build Coastguard Worker // multiplication.
194*9356374aSAndroid Build Coastguard Worker MultiplyBy(kTenToNth[n]);
195*9356374aSAndroid Build Coastguard Worker }
196*9356374aSAndroid Build Coastguard Worker }
197*9356374aSAndroid Build Coastguard Worker
198*9356374aSAndroid Build Coastguard Worker // Returns the value of 5**n, for non-negative n. This implementation uses
199*9356374aSAndroid Build Coastguard Worker // a lookup table, and is faster then seeding a BigUnsigned with 1 and calling
200*9356374aSAndroid Build Coastguard Worker // MultiplyByFiveToTheNth().
201*9356374aSAndroid Build Coastguard Worker static BigUnsigned FiveToTheNth(int n);
202*9356374aSAndroid Build Coastguard Worker
203*9356374aSAndroid Build Coastguard Worker // Multiplies by another BigUnsigned, in-place.
204*9356374aSAndroid Build Coastguard Worker template <int M>
MultiplyBy(const BigUnsigned<M> & other)205*9356374aSAndroid Build Coastguard Worker void MultiplyBy(const BigUnsigned<M>& other) {
206*9356374aSAndroid Build Coastguard Worker MultiplyBy(other.size(), other.words());
207*9356374aSAndroid Build Coastguard Worker }
208*9356374aSAndroid Build Coastguard Worker
SetToZero()209*9356374aSAndroid Build Coastguard Worker void SetToZero() {
210*9356374aSAndroid Build Coastguard Worker std::fill_n(words_, size_, 0u);
211*9356374aSAndroid Build Coastguard Worker size_ = 0;
212*9356374aSAndroid Build Coastguard Worker }
213*9356374aSAndroid Build Coastguard Worker
214*9356374aSAndroid Build Coastguard Worker // Returns the value of the nth word of this BigUnsigned. This is
215*9356374aSAndroid Build Coastguard Worker // range-checked, and returns 0 on out-of-bounds accesses.
GetWord(int index)216*9356374aSAndroid Build Coastguard Worker uint32_t GetWord(int index) const {
217*9356374aSAndroid Build Coastguard Worker if (index < 0 || index >= size_) {
218*9356374aSAndroid Build Coastguard Worker return 0;
219*9356374aSAndroid Build Coastguard Worker }
220*9356374aSAndroid Build Coastguard Worker return words_[index];
221*9356374aSAndroid Build Coastguard Worker }
222*9356374aSAndroid Build Coastguard Worker
223*9356374aSAndroid Build Coastguard Worker // Returns this integer as a decimal string. This is not used in the decimal-
224*9356374aSAndroid Build Coastguard Worker // to-binary conversion; it is intended to aid in testing.
225*9356374aSAndroid Build Coastguard Worker std::string ToString() const;
226*9356374aSAndroid Build Coastguard Worker
size()227*9356374aSAndroid Build Coastguard Worker int size() const { return size_; }
words()228*9356374aSAndroid Build Coastguard Worker const uint32_t* words() const { return words_; }
229*9356374aSAndroid Build Coastguard Worker
230*9356374aSAndroid Build Coastguard Worker private:
231*9356374aSAndroid Build Coastguard Worker // Reads the number between [begin, end), possibly containing a decimal point,
232*9356374aSAndroid Build Coastguard Worker // into this BigUnsigned.
233*9356374aSAndroid Build Coastguard Worker //
234*9356374aSAndroid Build Coastguard Worker // Callers are required to ensure [begin, end) contains a valid number, with
235*9356374aSAndroid Build Coastguard Worker // one or more decimal digits and at most one decimal point. This routine
236*9356374aSAndroid Build Coastguard Worker // will behave unpredictably if these preconditions are not met.
237*9356374aSAndroid Build Coastguard Worker //
238*9356374aSAndroid Build Coastguard Worker // Only the first `significant_digits` digits are read. Digits beyond this
239*9356374aSAndroid Build Coastguard Worker // limit are "sticky": If the final significant digit is 0 or 5, and if any
240*9356374aSAndroid Build Coastguard Worker // dropped digit is nonzero, then that final significant digit is adjusted up
241*9356374aSAndroid Build Coastguard Worker // to 1 or 6. This adjustment allows for precise rounding.
242*9356374aSAndroid Build Coastguard Worker //
243*9356374aSAndroid Build Coastguard Worker // Returns `exponent_adjustment`, a power-of-ten exponent adjustment to
244*9356374aSAndroid Build Coastguard Worker // account for the decimal point and for dropped significant digits. After
245*9356374aSAndroid Build Coastguard Worker // this function returns,
246*9356374aSAndroid Build Coastguard Worker // actual_value_of_parsed_string ~= *this * 10**exponent_adjustment.
247*9356374aSAndroid Build Coastguard Worker int ReadDigits(const char* begin, const char* end, int significant_digits);
248*9356374aSAndroid Build Coastguard Worker
249*9356374aSAndroid Build Coastguard Worker // Performs a step of big integer multiplication. This computes the full
250*9356374aSAndroid Build Coastguard Worker // (64-bit-wide) values that should be added at the given index (step), and
251*9356374aSAndroid Build Coastguard Worker // adds to that location in-place.
252*9356374aSAndroid Build Coastguard Worker //
253*9356374aSAndroid Build Coastguard Worker // Because our math all occurs in place, we must multiply starting from the
254*9356374aSAndroid Build Coastguard Worker // highest word working downward. (This is a bit more expensive due to the
255*9356374aSAndroid Build Coastguard Worker // extra carries involved.)
256*9356374aSAndroid Build Coastguard Worker //
257*9356374aSAndroid Build Coastguard Worker // This must be called in steps, for each word to be calculated, starting from
258*9356374aSAndroid Build Coastguard Worker // the high end and working down to 0. The first value of `step` should be
259*9356374aSAndroid Build Coastguard Worker // `std::min(original_size + other.size_ - 2, max_words - 1)`.
260*9356374aSAndroid Build Coastguard Worker // The reason for this expression is that multiplying the i'th word from one
261*9356374aSAndroid Build Coastguard Worker // multiplicand and the j'th word of another multiplicand creates a
262*9356374aSAndroid Build Coastguard Worker // two-word-wide value to be stored at the (i+j)'th element. The highest
263*9356374aSAndroid Build Coastguard Worker // word indices we will access are `original_size - 1` from this object, and
264*9356374aSAndroid Build Coastguard Worker // `other.size_ - 1` from our operand. Therefore,
265*9356374aSAndroid Build Coastguard Worker // `original_size + other.size_ - 2` is the first step we should calculate,
266*9356374aSAndroid Build Coastguard Worker // but limited on an upper bound by max_words.
267*9356374aSAndroid Build Coastguard Worker
268*9356374aSAndroid Build Coastguard Worker // Working from high-to-low ensures that we do not overwrite the portions of
269*9356374aSAndroid Build Coastguard Worker // the initial value of *this which are still needed for later steps.
270*9356374aSAndroid Build Coastguard Worker //
271*9356374aSAndroid Build Coastguard Worker // Once called with step == 0, *this contains the result of the
272*9356374aSAndroid Build Coastguard Worker // multiplication.
273*9356374aSAndroid Build Coastguard Worker //
274*9356374aSAndroid Build Coastguard Worker // `original_size` is the size_ of *this before the first call to
275*9356374aSAndroid Build Coastguard Worker // MultiplyStep(). `other_words` and `other_size` are the contents of our
276*9356374aSAndroid Build Coastguard Worker // operand. `step` is the step to perform, as described above.
277*9356374aSAndroid Build Coastguard Worker void MultiplyStep(int original_size, const uint32_t* other_words,
278*9356374aSAndroid Build Coastguard Worker int other_size, int step);
279*9356374aSAndroid Build Coastguard Worker
MultiplyBy(int other_size,const uint32_t * other_words)280*9356374aSAndroid Build Coastguard Worker void MultiplyBy(int other_size, const uint32_t* other_words) {
281*9356374aSAndroid Build Coastguard Worker const int original_size = size_;
282*9356374aSAndroid Build Coastguard Worker const int first_step =
283*9356374aSAndroid Build Coastguard Worker (std::min)(original_size + other_size - 2, max_words - 1);
284*9356374aSAndroid Build Coastguard Worker for (int step = first_step; step >= 0; --step) {
285*9356374aSAndroid Build Coastguard Worker MultiplyStep(original_size, other_words, other_size, step);
286*9356374aSAndroid Build Coastguard Worker }
287*9356374aSAndroid Build Coastguard Worker }
288*9356374aSAndroid Build Coastguard Worker
289*9356374aSAndroid Build Coastguard Worker // Adds a 32-bit value to the index'th word, with carry.
AddWithCarry(int index,uint32_t value)290*9356374aSAndroid Build Coastguard Worker void AddWithCarry(int index, uint32_t value) {
291*9356374aSAndroid Build Coastguard Worker if (value) {
292*9356374aSAndroid Build Coastguard Worker while (index < max_words && value > 0) {
293*9356374aSAndroid Build Coastguard Worker words_[index] += value;
294*9356374aSAndroid Build Coastguard Worker // carry if we overflowed in this word:
295*9356374aSAndroid Build Coastguard Worker if (value > words_[index]) {
296*9356374aSAndroid Build Coastguard Worker value = 1;
297*9356374aSAndroid Build Coastguard Worker ++index;
298*9356374aSAndroid Build Coastguard Worker } else {
299*9356374aSAndroid Build Coastguard Worker value = 0;
300*9356374aSAndroid Build Coastguard Worker }
301*9356374aSAndroid Build Coastguard Worker }
302*9356374aSAndroid Build Coastguard Worker size_ = (std::min)(max_words, (std::max)(index + 1, size_));
303*9356374aSAndroid Build Coastguard Worker }
304*9356374aSAndroid Build Coastguard Worker }
305*9356374aSAndroid Build Coastguard Worker
AddWithCarry(int index,uint64_t value)306*9356374aSAndroid Build Coastguard Worker void AddWithCarry(int index, uint64_t value) {
307*9356374aSAndroid Build Coastguard Worker if (value && index < max_words) {
308*9356374aSAndroid Build Coastguard Worker uint32_t high = value >> 32;
309*9356374aSAndroid Build Coastguard Worker uint32_t low = value & 0xffffffff;
310*9356374aSAndroid Build Coastguard Worker words_[index] += low;
311*9356374aSAndroid Build Coastguard Worker if (words_[index] < low) {
312*9356374aSAndroid Build Coastguard Worker ++high;
313*9356374aSAndroid Build Coastguard Worker if (high == 0) {
314*9356374aSAndroid Build Coastguard Worker // Carry from the low word caused our high word to overflow.
315*9356374aSAndroid Build Coastguard Worker // Short circuit here to do the right thing.
316*9356374aSAndroid Build Coastguard Worker AddWithCarry(index + 2, static_cast<uint32_t>(1));
317*9356374aSAndroid Build Coastguard Worker return;
318*9356374aSAndroid Build Coastguard Worker }
319*9356374aSAndroid Build Coastguard Worker }
320*9356374aSAndroid Build Coastguard Worker if (high > 0) {
321*9356374aSAndroid Build Coastguard Worker AddWithCarry(index + 1, high);
322*9356374aSAndroid Build Coastguard Worker } else {
323*9356374aSAndroid Build Coastguard Worker // Normally 32-bit AddWithCarry() sets size_, but since we don't call
324*9356374aSAndroid Build Coastguard Worker // it when `high` is 0, do it ourselves here.
325*9356374aSAndroid Build Coastguard Worker size_ = (std::min)(max_words, (std::max)(index + 1, size_));
326*9356374aSAndroid Build Coastguard Worker }
327*9356374aSAndroid Build Coastguard Worker }
328*9356374aSAndroid Build Coastguard Worker }
329*9356374aSAndroid Build Coastguard Worker
330*9356374aSAndroid Build Coastguard Worker // Divide this in place by a constant divisor. Returns the remainder of the
331*9356374aSAndroid Build Coastguard Worker // division.
332*9356374aSAndroid Build Coastguard Worker template <uint32_t divisor>
DivMod()333*9356374aSAndroid Build Coastguard Worker uint32_t DivMod() {
334*9356374aSAndroid Build Coastguard Worker uint64_t accumulator = 0;
335*9356374aSAndroid Build Coastguard Worker for (int i = size_ - 1; i >= 0; --i) {
336*9356374aSAndroid Build Coastguard Worker accumulator <<= 32;
337*9356374aSAndroid Build Coastguard Worker accumulator += words_[i];
338*9356374aSAndroid Build Coastguard Worker // accumulator / divisor will never overflow an int32_t in this loop
339*9356374aSAndroid Build Coastguard Worker words_[i] = static_cast<uint32_t>(accumulator / divisor);
340*9356374aSAndroid Build Coastguard Worker accumulator = accumulator % divisor;
341*9356374aSAndroid Build Coastguard Worker }
342*9356374aSAndroid Build Coastguard Worker while (size_ > 0 && words_[size_ - 1] == 0) {
343*9356374aSAndroid Build Coastguard Worker --size_;
344*9356374aSAndroid Build Coastguard Worker }
345*9356374aSAndroid Build Coastguard Worker return static_cast<uint32_t>(accumulator);
346*9356374aSAndroid Build Coastguard Worker }
347*9356374aSAndroid Build Coastguard Worker
348*9356374aSAndroid Build Coastguard Worker // The number of elements in words_ that may carry significant values.
349*9356374aSAndroid Build Coastguard Worker // All elements beyond this point are 0.
350*9356374aSAndroid Build Coastguard Worker //
351*9356374aSAndroid Build Coastguard Worker // When size_ is 0, this BigUnsigned stores the value 0.
352*9356374aSAndroid Build Coastguard Worker // When size_ is nonzero, is *not* guaranteed that words_[size_ - 1] is
353*9356374aSAndroid Build Coastguard Worker // nonzero. This can occur due to overflow truncation.
354*9356374aSAndroid Build Coastguard Worker // In particular, x.size_ != y.size_ does *not* imply x != y.
355*9356374aSAndroid Build Coastguard Worker int size_;
356*9356374aSAndroid Build Coastguard Worker uint32_t words_[max_words];
357*9356374aSAndroid Build Coastguard Worker };
358*9356374aSAndroid Build Coastguard Worker
359*9356374aSAndroid Build Coastguard Worker // Compares two big integer instances.
360*9356374aSAndroid Build Coastguard Worker //
361*9356374aSAndroid Build Coastguard Worker // Returns -1 if lhs < rhs, 0 if lhs == rhs, and 1 if lhs > rhs.
362*9356374aSAndroid Build Coastguard Worker template <int N, int M>
Compare(const BigUnsigned<N> & lhs,const BigUnsigned<M> & rhs)363*9356374aSAndroid Build Coastguard Worker int Compare(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
364*9356374aSAndroid Build Coastguard Worker int limit = (std::max)(lhs.size(), rhs.size());
365*9356374aSAndroid Build Coastguard Worker for (int i = limit - 1; i >= 0; --i) {
366*9356374aSAndroid Build Coastguard Worker const uint32_t lhs_word = lhs.GetWord(i);
367*9356374aSAndroid Build Coastguard Worker const uint32_t rhs_word = rhs.GetWord(i);
368*9356374aSAndroid Build Coastguard Worker if (lhs_word < rhs_word) {
369*9356374aSAndroid Build Coastguard Worker return -1;
370*9356374aSAndroid Build Coastguard Worker } else if (lhs_word > rhs_word) {
371*9356374aSAndroid Build Coastguard Worker return 1;
372*9356374aSAndroid Build Coastguard Worker }
373*9356374aSAndroid Build Coastguard Worker }
374*9356374aSAndroid Build Coastguard Worker return 0;
375*9356374aSAndroid Build Coastguard Worker }
376*9356374aSAndroid Build Coastguard Worker
377*9356374aSAndroid Build Coastguard Worker template <int N, int M>
378*9356374aSAndroid Build Coastguard Worker bool operator==(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
379*9356374aSAndroid Build Coastguard Worker int limit = (std::max)(lhs.size(), rhs.size());
380*9356374aSAndroid Build Coastguard Worker for (int i = 0; i < limit; ++i) {
381*9356374aSAndroid Build Coastguard Worker if (lhs.GetWord(i) != rhs.GetWord(i)) {
382*9356374aSAndroid Build Coastguard Worker return false;
383*9356374aSAndroid Build Coastguard Worker }
384*9356374aSAndroid Build Coastguard Worker }
385*9356374aSAndroid Build Coastguard Worker return true;
386*9356374aSAndroid Build Coastguard Worker }
387*9356374aSAndroid Build Coastguard Worker
388*9356374aSAndroid Build Coastguard Worker template <int N, int M>
389*9356374aSAndroid Build Coastguard Worker bool operator!=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
390*9356374aSAndroid Build Coastguard Worker return !(lhs == rhs);
391*9356374aSAndroid Build Coastguard Worker }
392*9356374aSAndroid Build Coastguard Worker
393*9356374aSAndroid Build Coastguard Worker template <int N, int M>
394*9356374aSAndroid Build Coastguard Worker bool operator<(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
395*9356374aSAndroid Build Coastguard Worker return Compare(lhs, rhs) == -1;
396*9356374aSAndroid Build Coastguard Worker }
397*9356374aSAndroid Build Coastguard Worker
398*9356374aSAndroid Build Coastguard Worker template <int N, int M>
399*9356374aSAndroid Build Coastguard Worker bool operator>(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
400*9356374aSAndroid Build Coastguard Worker return rhs < lhs;
401*9356374aSAndroid Build Coastguard Worker }
402*9356374aSAndroid Build Coastguard Worker template <int N, int M>
403*9356374aSAndroid Build Coastguard Worker bool operator<=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
404*9356374aSAndroid Build Coastguard Worker return !(rhs < lhs);
405*9356374aSAndroid Build Coastguard Worker }
406*9356374aSAndroid Build Coastguard Worker template <int N, int M>
407*9356374aSAndroid Build Coastguard Worker bool operator>=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
408*9356374aSAndroid Build Coastguard Worker return !(lhs < rhs);
409*9356374aSAndroid Build Coastguard Worker }
410*9356374aSAndroid Build Coastguard Worker
411*9356374aSAndroid Build Coastguard Worker // Output operator for BigUnsigned, for testing purposes only.
412*9356374aSAndroid Build Coastguard Worker template <int N>
413*9356374aSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const BigUnsigned<N>& num) {
414*9356374aSAndroid Build Coastguard Worker return os << num.ToString();
415*9356374aSAndroid Build Coastguard Worker }
416*9356374aSAndroid Build Coastguard Worker
417*9356374aSAndroid Build Coastguard Worker // Explicit instantiation declarations for the sizes of BigUnsigned that we
418*9356374aSAndroid Build Coastguard Worker // are using.
419*9356374aSAndroid Build Coastguard Worker //
420*9356374aSAndroid Build Coastguard Worker // For now, the choices of 4 and 84 are arbitrary; 4 is a small value that is
421*9356374aSAndroid Build Coastguard Worker // still bigger than an int128, and 84 is a large value we will want to use
422*9356374aSAndroid Build Coastguard Worker // in the from_chars implementation.
423*9356374aSAndroid Build Coastguard Worker //
424*9356374aSAndroid Build Coastguard Worker // Comments justifying the use of 84 belong in the from_chars implementation,
425*9356374aSAndroid Build Coastguard Worker // and will be added in a follow-up CL.
426*9356374aSAndroid Build Coastguard Worker extern template class BigUnsigned<4>;
427*9356374aSAndroid Build Coastguard Worker extern template class BigUnsigned<84>;
428*9356374aSAndroid Build Coastguard Worker
429*9356374aSAndroid Build Coastguard Worker } // namespace strings_internal
430*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
431*9356374aSAndroid Build Coastguard Worker } // namespace absl
432*9356374aSAndroid Build Coastguard Worker
433*9356374aSAndroid Build Coastguard Worker #endif // ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_
434