1 | //===-- A class to manipulate wide integers. --------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLVM_LIBC_SRC___SUPPORT_BIG_INT_H |
10 | #define LLVM_LIBC_SRC___SUPPORT_BIG_INT_H |
11 | |
12 | #include "src/__support/CPP/array.h" |
13 | #include "src/__support/CPP/bit.h" // countl_zero |
14 | #include "src/__support/CPP/limits.h" |
15 | #include "src/__support/CPP/optional.h" |
16 | #include "src/__support/CPP/type_traits.h" |
17 | #include "src/__support/macros/attributes.h" // LIBC_INLINE |
18 | #include "src/__support/macros/config.h" |
19 | #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY |
20 | #include "src/__support/macros/properties/compiler.h" // LIBC_COMPILER_IS_CLANG |
21 | #include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128, LIBC_TYPES_HAS_INT64 |
22 | #include "src/__support/math_extras.h" // add_with_carry, sub_with_borrow |
23 | #include "src/__support/number_pair.h" |
24 | |
25 | #include <stddef.h> // For size_t |
26 | #include <stdint.h> |
27 | |
28 | namespace LIBC_NAMESPACE_DECL { |
29 | |
30 | namespace multiword { |
31 | |
32 | // A type trait mapping unsigned integers to their half-width unsigned |
33 | // counterparts. |
34 | template <typename T> struct half_width; |
35 | template <> struct half_width<uint16_t> : cpp::type_identity<uint8_t> {}; |
36 | template <> struct half_width<uint32_t> : cpp::type_identity<uint16_t> {}; |
37 | #ifdef LIBC_TYPES_HAS_INT64 |
38 | template <> struct half_width<uint64_t> : cpp::type_identity<uint32_t> {}; |
39 | #ifdef LIBC_TYPES_HAS_INT128 |
40 | template <> struct half_width<__uint128_t> : cpp::type_identity<uint64_t> {}; |
41 | #endif // LIBC_TYPES_HAS_INT128 |
42 | #endif // LIBC_TYPES_HAS_INT64 |
43 | template <typename T> using half_width_t = typename half_width<T>::type; |
44 | |
45 | // An array of two elements that can be used in multiword operations. |
46 | template <typename T> struct DoubleWide final : cpp::array<T, 2> { |
47 | using UP = cpp::array<T, 2>; |
48 | using UP::UP; |
49 | LIBC_INLINE constexpr DoubleWide(T lo, T hi) : UP({lo, hi}) {} |
50 | }; |
51 | |
52 | // Converts an unsigned value into a DoubleWide<half_width_t<T>>. |
53 | template <typename T> LIBC_INLINE constexpr auto split(T value) { |
54 | static_assert(cpp::is_unsigned_v<T>); |
55 | using half_type = half_width_t<T>; |
56 | return DoubleWide<half_type>( |
57 | half_type(value), |
58 | half_type(value >> cpp::numeric_limits<half_type>::digits)); |
59 | } |
60 | |
61 | // The low part of a DoubleWide value. |
62 | template <typename T> LIBC_INLINE constexpr T lo(const DoubleWide<T> &value) { |
63 | return value[0]; |
64 | } |
65 | // The high part of a DoubleWide value. |
66 | template <typename T> LIBC_INLINE constexpr T hi(const DoubleWide<T> &value) { |
67 | return value[1]; |
68 | } |
69 | // The low part of an unsigned value. |
70 | template <typename T> LIBC_INLINE constexpr half_width_t<T> lo(T value) { |
71 | return lo(split(value)); |
72 | } |
73 | // The high part of an unsigned value. |
74 | template <typename T> LIBC_INLINE constexpr half_width_t<T> hi(T value) { |
75 | return hi(split(value)); |
76 | } |
77 | |
78 | // Returns 'a' times 'b' in a DoubleWide<word>. Cannot overflow by construction. |
79 | template <typename word> |
80 | LIBC_INLINE constexpr DoubleWide<word> mul2(word a, word b) { |
81 | if constexpr (cpp::is_same_v<word, uint8_t>) { |
82 | return split<uint16_t>(value: uint16_t(a) * uint16_t(b)); |
83 | } else if constexpr (cpp::is_same_v<word, uint16_t>) { |
84 | return split<uint32_t>(value: uint32_t(a) * uint32_t(b)); |
85 | } |
86 | #ifdef LIBC_TYPES_HAS_INT64 |
87 | else if constexpr (cpp::is_same_v<word, uint32_t>) { |
88 | return split<uint64_t>(value: uint64_t(a) * uint64_t(b)); |
89 | } |
90 | #endif |
91 | #ifdef LIBC_TYPES_HAS_INT128 |
92 | else if constexpr (cpp::is_same_v<word, uint64_t>) { |
93 | return split<__uint128_t>(value: __uint128_t(a) * __uint128_t(b)); |
94 | } |
95 | #endif |
96 | else { |
97 | using half_word = half_width_t<word>; |
98 | const auto shiftl = [](word value) -> word { |
99 | return value << cpp::numeric_limits<half_word>::digits; |
100 | }; |
101 | const auto shiftr = [](word value) -> word { |
102 | return value >> cpp::numeric_limits<half_word>::digits; |
103 | }; |
104 | // Here we do a one digit multiplication where 'a' and 'b' are of type |
105 | // word. We split 'a' and 'b' into half words and perform the classic long |
106 | // multiplication with 'a' and 'b' being two-digit numbers. |
107 | |
108 | // a a_hi a_lo |
109 | // x b => x b_hi b_lo |
110 | // ---- ----------- |
111 | // c result |
112 | // We convert 'lo' and 'hi' from 'half_word' to 'word' so multiplication |
113 | // doesn't overflow. |
114 | const word a_lo = lo(a); |
115 | const word b_lo = lo(b); |
116 | const word a_hi = hi(a); |
117 | const word b_hi = hi(b); |
118 | const word step1 = b_lo * a_lo; // no overflow; |
119 | const word step2 = b_lo * a_hi; // no overflow; |
120 | const word step3 = b_hi * a_lo; // no overflow; |
121 | const word step4 = b_hi * a_hi; // no overflow; |
122 | word lo_digit = step1; |
123 | word hi_digit = step4; |
124 | const word no_carry = 0; |
125 | word carry; |
126 | word _; // unused carry variable. |
127 | lo_digit = add_with_carry<word>(lo_digit, shiftl(step2), no_carry, carry); |
128 | hi_digit = add_with_carry<word>(hi_digit, shiftr(step2), carry, _); |
129 | lo_digit = add_with_carry<word>(lo_digit, shiftl(step3), no_carry, carry); |
130 | hi_digit = add_with_carry<word>(hi_digit, shiftr(step3), carry, _); |
131 | return DoubleWide<word>(lo_digit, hi_digit); |
132 | } |
133 | } |
134 | |
135 | // In-place 'dst op= rhs' with operation with carry propagation. Returns carry. |
136 | template <typename Function, typename word, size_t N, size_t M> |
137 | LIBC_INLINE constexpr word inplace_binop(Function op_with_carry, |
138 | cpp::array<word, N> &dst, |
139 | const cpp::array<word, M> &rhs) { |
140 | static_assert(N >= M); |
141 | word carry_out = 0; |
142 | for (size_t i = 0; i < N; ++i) { |
143 | const bool has_rhs_value = i < M; |
144 | const word rhs_value = has_rhs_value ? rhs[i] : 0; |
145 | const word carry_in = carry_out; |
146 | dst[i] = op_with_carry(dst[i], rhs_value, carry_in, carry_out); |
147 | // stop early when rhs is over and no carry is to be propagated. |
148 | if (!has_rhs_value && carry_out == 0) |
149 | break; |
150 | } |
151 | return carry_out; |
152 | } |
153 | |
154 | // In-place addition. Returns carry. |
155 | template <typename word, size_t N, size_t M> |
156 | LIBC_INLINE constexpr word add_with_carry(cpp::array<word, N> &dst, |
157 | const cpp::array<word, M> &rhs) { |
158 | return inplace_binop(LIBC_NAMESPACE::add_with_carry<word>, dst, rhs); |
159 | } |
160 | |
161 | // In-place subtraction. Returns borrow. |
162 | template <typename word, size_t N, size_t M> |
163 | LIBC_INLINE constexpr word sub_with_borrow(cpp::array<word, N> &dst, |
164 | const cpp::array<word, M> &rhs) { |
165 | return inplace_binop(LIBC_NAMESPACE::sub_with_borrow<word>, dst, rhs); |
166 | } |
167 | |
168 | // In-place multiply-add. Returns carry. |
169 | // i.e., 'dst += b * c' |
170 | template <typename word, size_t N> |
171 | LIBC_INLINE constexpr word mul_add_with_carry(cpp::array<word, N> &dst, word b, |
172 | word c) { |
173 | return add_with_carry(dst, mul2(b, c)); |
174 | } |
175 | |
176 | // An array of two elements serving as an accumulator during multiword |
177 | // computations. |
178 | template <typename T> struct Accumulator final : cpp::array<T, 2> { |
179 | using UP = cpp::array<T, 2>; |
180 | LIBC_INLINE constexpr Accumulator() : UP({0, 0}) {} |
181 | LIBC_INLINE constexpr T advance(T carry_in) { |
182 | auto result = UP::front(); |
183 | UP::front() = UP::back(); |
184 | UP::back() = carry_in; |
185 | return result; |
186 | } |
187 | LIBC_INLINE constexpr T sum() const { return UP::front(); } |
188 | LIBC_INLINE constexpr T carry() const { return UP::back(); } |
189 | }; |
190 | |
191 | // In-place multiplication by a single word. Returns carry. |
192 | template <typename word, size_t N> |
193 | LIBC_INLINE constexpr word scalar_multiply_with_carry(cpp::array<word, N> &dst, |
194 | word x) { |
195 | Accumulator<word> acc; |
196 | for (auto &val : dst) { |
197 | const word carry = mul_add_with_carry(acc, val, x); |
198 | val = acc.advance(carry); |
199 | } |
200 | return acc.carry(); |
201 | } |
202 | |
203 | // Multiplication of 'lhs' by 'rhs' into 'dst'. Returns carry. |
204 | // This function is safe to use for signed numbers. |
205 | // https://stackoverflow.com/a/20793834 |
206 | // https://pages.cs.wisc.edu/%7Emarkhill/cs354/Fall2008/beyond354/int.mult.html |
207 | template <typename word, size_t O, size_t M, size_t N> |
208 | LIBC_INLINE constexpr word multiply_with_carry(cpp::array<word, O> &dst, |
209 | const cpp::array<word, M> &lhs, |
210 | const cpp::array<word, N> &rhs) { |
211 | static_assert(O >= M + N); |
212 | Accumulator<word> acc; |
213 | for (size_t i = 0; i < O; ++i) { |
214 | const size_t lower_idx = i < N ? 0 : i - N + 1; |
215 | const size_t upper_idx = i < M ? i : M - 1; |
216 | word carry = 0; |
217 | for (size_t j = lower_idx; j <= upper_idx; ++j) |
218 | carry += mul_add_with_carry(acc, lhs[j], rhs[i - j]); |
219 | dst[i] = acc.advance(carry); |
220 | } |
221 | return acc.carry(); |
222 | } |
223 | |
224 | template <typename word, size_t N> |
225 | LIBC_INLINE constexpr void quick_mul_hi(cpp::array<word, N> &dst, |
226 | const cpp::array<word, N> &lhs, |
227 | const cpp::array<word, N> &rhs) { |
228 | Accumulator<word> acc; |
229 | word carry = 0; |
230 | // First round of accumulation for those at N - 1 in the full product. |
231 | for (size_t i = 0; i < N; ++i) |
232 | carry += mul_add_with_carry(acc, lhs[i], rhs[N - 1 - i]); |
233 | for (size_t i = N; i < 2 * N - 1; ++i) { |
234 | acc.advance(carry); |
235 | carry = 0; |
236 | for (size_t j = i - N + 1; j < N; ++j) |
237 | carry += mul_add_with_carry(acc, lhs[j], rhs[i - j]); |
238 | dst[i - N] = acc.sum(); |
239 | } |
240 | dst.back() = acc.carry(); |
241 | } |
242 | |
243 | template <typename word, size_t N> |
244 | LIBC_INLINE constexpr bool is_negative(const cpp::array<word, N> &array) { |
245 | using signed_word = cpp::make_signed_t<word>; |
246 | return cpp::bit_cast<signed_word>(array.back()) < 0; |
247 | } |
248 | |
249 | // An enum for the shift function below. |
250 | enum Direction { LEFT, RIGHT }; |
251 | |
252 | // A bitwise shift on an array of elements. |
253 | // 'offset' must be less than TOTAL_BITS (i.e., sizeof(word) * CHAR_BIT * N) |
254 | // otherwise the behavior is undefined. |
255 | template <Direction direction, bool is_signed, typename word, size_t N> |
256 | LIBC_INLINE constexpr cpp::array<word, N> shift(cpp::array<word, N> array, |
257 | size_t offset) { |
258 | static_assert(direction == LEFT || direction == RIGHT); |
259 | constexpr size_t WORD_BITS = cpp::numeric_limits<word>::digits; |
260 | #ifdef LIBC_TYPES_HAS_INT128 |
261 | constexpr size_t TOTAL_BITS = N * WORD_BITS; |
262 | if constexpr (TOTAL_BITS == 128) { |
263 | using type = cpp::conditional_t<is_signed, __int128_t, __uint128_t>; |
264 | auto tmp = cpp::bit_cast<type>(array); |
265 | if constexpr (direction == LEFT) |
266 | tmp <<= offset; |
267 | else |
268 | tmp >>= offset; |
269 | return cpp::bit_cast<cpp::array<word, N>>(tmp); |
270 | } |
271 | #endif |
272 | if (LIBC_UNLIKELY(offset == 0)) |
273 | return array; |
274 | const bool is_neg = is_signed && is_negative(array); |
275 | constexpr auto at = [](size_t index) -> int { |
276 | // reverse iteration when direction == LEFT. |
277 | if constexpr (direction == LEFT) |
278 | return int(N) - int(index) - 1; |
279 | return int(index); |
280 | }; |
281 | const auto safe_get_at = [&](size_t index) -> word { |
282 | // return appropriate value when accessing out of bound elements. |
283 | const int i = at(index); |
284 | if (i < 0) |
285 | return 0; |
286 | if (i >= int(N)) |
287 | return is_neg ? cpp::numeric_limits<word>::max() : 0; |
288 | return array[static_cast<unsigned>(i)]; |
289 | }; |
290 | const size_t index_offset = offset / WORD_BITS; |
291 | const size_t bit_offset = offset % WORD_BITS; |
292 | #ifdef LIBC_COMPILER_IS_CLANG |
293 | __builtin_assume(index_offset < N); |
294 | #endif |
295 | cpp::array<word, N> out = {}; |
296 | for (size_t index = 0; index < N; ++index) { |
297 | const word part1 = safe_get_at(index + index_offset); |
298 | const word part2 = safe_get_at(index + index_offset + 1); |
299 | word &dst = out[static_cast<unsigned>(at(index))]; |
300 | if (bit_offset == 0) |
301 | dst = part1; // no crosstalk between parts. |
302 | else if constexpr (direction == LEFT) |
303 | dst = static_cast<word>((part1 << bit_offset) | |
304 | (part2 >> (WORD_BITS - bit_offset))); |
305 | else |
306 | dst = static_cast<word>((part1 >> bit_offset) | |
307 | (part2 << (WORD_BITS - bit_offset))); |
308 | } |
309 | return out; |
310 | } |
311 | |
312 | #define DECLARE_COUNTBIT(NAME, INDEX_EXPR) \ |
313 | template <typename word, size_t N> \ |
314 | LIBC_INLINE constexpr int NAME(const cpp::array<word, N> &val) { \ |
315 | int bit_count = 0; \ |
316 | for (size_t i = 0; i < N; ++i) { \ |
317 | const int word_count = cpp::NAME<word>(val[INDEX_EXPR]); \ |
318 | bit_count += word_count; \ |
319 | if (word_count != cpp::numeric_limits<word>::digits) \ |
320 | break; \ |
321 | } \ |
322 | return bit_count; \ |
323 | } |
324 | |
325 | DECLARE_COUNTBIT(countr_zero, i) // iterating forward |
326 | DECLARE_COUNTBIT(countr_one, i) // iterating forward |
327 | DECLARE_COUNTBIT(countl_zero, N - i - 1) // iterating backward |
328 | DECLARE_COUNTBIT(countl_one, N - i - 1) // iterating backward |
329 | |
330 | } // namespace multiword |
331 | |
332 | template <size_t Bits, bool Signed, typename WordType = uint64_t> |
333 | struct BigInt { |
334 | private: |
335 | static_assert(cpp::is_integral_v<WordType> && cpp::is_unsigned_v<WordType>, |
336 | "WordType must be unsigned integer." ); |
337 | |
338 | struct Division { |
339 | BigInt quotient; |
340 | BigInt remainder; |
341 | }; |
342 | |
343 | public: |
344 | using word_type = WordType; |
345 | using unsigned_type = BigInt<Bits, false, word_type>; |
346 | using signed_type = BigInt<Bits, true, word_type>; |
347 | |
348 | LIBC_INLINE_VAR static constexpr bool SIGNED = Signed; |
349 | LIBC_INLINE_VAR static constexpr size_t BITS = Bits; |
350 | LIBC_INLINE_VAR |
351 | static constexpr size_t WORD_SIZE = sizeof(WordType) * CHAR_BIT; |
352 | |
353 | static_assert(Bits > 0 && Bits % WORD_SIZE == 0, |
354 | "Number of bits in BigInt should be a multiple of WORD_SIZE." ); |
355 | |
356 | LIBC_INLINE_VAR static constexpr size_t WORD_COUNT = Bits / WORD_SIZE; |
357 | |
358 | cpp::array<WordType, WORD_COUNT> val{}; // zero initialized. |
359 | |
360 | LIBC_INLINE constexpr BigInt() = default; |
361 | |
362 | LIBC_INLINE constexpr BigInt(const BigInt &other) = default; |
363 | |
364 | template <size_t OtherBits, bool OtherSigned, typename OtherWordType> |
365 | LIBC_INLINE constexpr BigInt( |
366 | const BigInt<OtherBits, OtherSigned, OtherWordType> &other) { |
367 | using BigIntOther = BigInt<OtherBits, OtherSigned, OtherWordType>; |
368 | const bool should_sign_extend = Signed && other.is_neg(); |
369 | |
370 | static_assert(!(Bits == OtherBits && WORD_SIZE != BigIntOther::WORD_SIZE) && |
371 | "This is currently untested for casting between bigints with " |
372 | "the same bit width but different word sizes." ); |
373 | |
374 | if constexpr (BigIntOther::WORD_SIZE < WORD_SIZE) { |
375 | // OtherWordType is smaller |
376 | constexpr size_t WORD_SIZE_RATIO = WORD_SIZE / BigIntOther::WORD_SIZE; |
377 | static_assert( |
378 | (WORD_SIZE % BigIntOther::WORD_SIZE) == 0 && |
379 | "Word types must be multiples of each other for correct conversion." ); |
380 | if constexpr (OtherBits >= Bits) { // truncate |
381 | // for each big word |
382 | for (size_t i = 0; i < WORD_COUNT; ++i) { |
383 | WordType cur_word = 0; |
384 | // combine WORD_SIZE_RATIO small words into a big word |
385 | for (size_t j = 0; j < WORD_SIZE_RATIO; ++j) |
386 | cur_word |= static_cast<WordType>(other[(i * WORD_SIZE_RATIO) + j]) |
387 | << (BigIntOther::WORD_SIZE * j); |
388 | |
389 | val[i] = cur_word; |
390 | } |
391 | } else { // zero or sign extend |
392 | size_t i = 0; |
393 | WordType cur_word = 0; |
394 | // for each small word |
395 | for (; i < BigIntOther::WORD_COUNT; ++i) { |
396 | // combine WORD_SIZE_RATIO small words into a big word |
397 | cur_word |= static_cast<WordType>(other[i]) |
398 | << (BigIntOther::WORD_SIZE * (i % WORD_SIZE_RATIO)); |
399 | // if we've completed a big word, copy it into place and reset |
400 | if ((i % WORD_SIZE_RATIO) == WORD_SIZE_RATIO - 1) { |
401 | val[i / WORD_SIZE_RATIO] = cur_word; |
402 | cur_word = 0; |
403 | } |
404 | } |
405 | // Pretend there are extra words of the correct sign extension as needed |
406 | |
407 | const WordType extension_bits = |
408 | should_sign_extend ? cpp::numeric_limits<WordType>::max() |
409 | : cpp::numeric_limits<WordType>::min(); |
410 | if ((i % WORD_SIZE_RATIO) != 0) { |
411 | cur_word |= static_cast<WordType>(extension_bits) |
412 | << (BigIntOther::WORD_SIZE * (i % WORD_SIZE_RATIO)); |
413 | } |
414 | // Copy the last word into place. |
415 | val[(i / WORD_SIZE_RATIO)] = cur_word; |
416 | extend(index: (i / WORD_SIZE_RATIO) + 1, is_neg: should_sign_extend); |
417 | } |
418 | } else if constexpr (BigIntOther::WORD_SIZE == WORD_SIZE) { |
419 | if constexpr (OtherBits >= Bits) { // truncate |
420 | for (size_t i = 0; i < WORD_COUNT; ++i) |
421 | val[i] = other[i]; |
422 | } else { // zero or sign extend |
423 | size_t i = 0; |
424 | for (; i < BigIntOther::WORD_COUNT; ++i) |
425 | val[i] = other[i]; |
426 | extend(index: i, is_neg: should_sign_extend); |
427 | } |
428 | } else { |
429 | // OtherWordType is bigger. |
430 | constexpr size_t WORD_SIZE_RATIO = BigIntOther::WORD_SIZE / WORD_SIZE; |
431 | static_assert( |
432 | (BigIntOther::WORD_SIZE % WORD_SIZE) == 0 && |
433 | "Word types must be multiples of each other for correct conversion." ); |
434 | if constexpr (OtherBits >= Bits) { // truncate |
435 | // for each small word |
436 | for (size_t i = 0; i < WORD_COUNT; ++i) { |
437 | // split each big word into WORD_SIZE_RATIO small words |
438 | val[i] = static_cast<WordType>(other[i / WORD_SIZE_RATIO] >> |
439 | ((i % WORD_SIZE_RATIO) * WORD_SIZE)); |
440 | } |
441 | } else { // zero or sign extend |
442 | size_t i = 0; |
443 | // for each big word |
444 | for (; i < BigIntOther::WORD_COUNT; ++i) { |
445 | // split each big word into WORD_SIZE_RATIO small words |
446 | for (size_t j = 0; j < WORD_SIZE_RATIO; ++j) |
447 | val[(i * WORD_SIZE_RATIO) + j] = |
448 | static_cast<WordType>(other[i] >> (j * WORD_SIZE)); |
449 | } |
450 | extend(index: i * WORD_SIZE_RATIO, is_neg: should_sign_extend); |
451 | } |
452 | } |
453 | } |
454 | |
455 | // Construct a BigInt from a C array. |
456 | template <size_t N> LIBC_INLINE constexpr BigInt(const WordType (&nums)[N]) { |
457 | static_assert(N == WORD_COUNT); |
458 | for (size_t i = 0; i < WORD_COUNT; ++i) |
459 | val[i] = nums[i]; |
460 | } |
461 | |
462 | LIBC_INLINE constexpr explicit BigInt( |
463 | const cpp::array<WordType, WORD_COUNT> &words) { |
464 | val = words; |
465 | } |
466 | |
467 | // Initialize the first word to |v| and the rest to 0. |
468 | template <typename T, typename = cpp::enable_if_t<cpp::is_integral_v<T>>> |
469 | LIBC_INLINE constexpr BigInt(T v) { |
470 | constexpr size_t T_SIZE = sizeof(T) * CHAR_BIT; |
471 | const bool is_neg = v < 0; |
472 | for (size_t i = 0; i < WORD_COUNT; ++i) { |
473 | if (v == 0) { |
474 | extend(index: i, is_neg); |
475 | return; |
476 | } |
477 | val[i] = static_cast<WordType>(v); |
478 | if constexpr (T_SIZE > WORD_SIZE) |
479 | v >>= WORD_SIZE; |
480 | else |
481 | v = 0; |
482 | } |
483 | } |
484 | LIBC_INLINE constexpr BigInt &operator=(const BigInt &other) = default; |
485 | |
486 | // constants |
487 | LIBC_INLINE static constexpr BigInt zero() { return BigInt(); } |
488 | LIBC_INLINE static constexpr BigInt one() { return BigInt(1); } |
489 | LIBC_INLINE static constexpr BigInt all_ones() { return ~zero(); } |
490 | LIBC_INLINE static constexpr BigInt min() { |
491 | BigInt out; |
492 | if constexpr (SIGNED) |
493 | out.set_msb(); |
494 | return out; |
495 | } |
496 | LIBC_INLINE static constexpr BigInt max() { |
497 | BigInt out = all_ones(); |
498 | if constexpr (SIGNED) |
499 | out.clear_msb(); |
500 | return out; |
501 | } |
502 | |
503 | // TODO: Reuse the Sign type. |
504 | LIBC_INLINE constexpr bool is_neg() const { return SIGNED && get_msb(); } |
505 | |
506 | template <size_t OtherBits, bool OtherSigned, typename OtherWordType> |
507 | LIBC_INLINE constexpr explicit |
508 | operator BigInt<OtherBits, OtherSigned, OtherWordType>() const { |
509 | return BigInt<OtherBits, OtherSigned, OtherWordType>(this); |
510 | } |
511 | |
512 | template <typename T> LIBC_INLINE constexpr explicit operator T() const { |
513 | return to<T>(); |
514 | } |
515 | |
516 | template <typename T> |
517 | LIBC_INLINE constexpr cpp::enable_if_t< |
518 | cpp::is_integral_v<T> && !cpp::is_same_v<T, bool>, T> |
519 | to() const { |
520 | constexpr size_t T_SIZE = sizeof(T) * CHAR_BIT; |
521 | T lo = static_cast<T>(val[0]); |
522 | if constexpr (T_SIZE <= WORD_SIZE) |
523 | return lo; |
524 | constexpr size_t MAX_COUNT = |
525 | T_SIZE > Bits ? WORD_COUNT : T_SIZE / WORD_SIZE; |
526 | for (size_t i = 1; i < MAX_COUNT; ++i) |
527 | lo += static_cast<T>(static_cast<T>(val[i]) << (WORD_SIZE * i)); |
528 | if constexpr (Signed && (T_SIZE > Bits)) { |
529 | // Extend sign for negative numbers. |
530 | constexpr T MASK = (~T(0) << Bits); |
531 | if (is_neg()) |
532 | lo |= MASK; |
533 | } |
534 | return lo; |
535 | } |
536 | |
537 | LIBC_INLINE constexpr explicit operator bool() const { return !is_zero(); } |
538 | |
539 | LIBC_INLINE constexpr bool is_zero() const { |
540 | for (auto part : val) |
541 | if (part != 0) |
542 | return false; |
543 | return true; |
544 | } |
545 | |
546 | // Add 'rhs' to this number and store the result in this number. |
547 | // Returns the carry value produced by the addition operation. |
548 | LIBC_INLINE constexpr WordType add_overflow(const BigInt &rhs) { |
549 | return multiword::add_with_carry(val, rhs.val); |
550 | } |
551 | |
552 | LIBC_INLINE constexpr BigInt operator+(const BigInt &other) const { |
553 | BigInt result = *this; |
554 | result.add_overflow(other); |
555 | return result; |
556 | } |
557 | |
558 | // This will only apply when initializing a variable from constant values, so |
559 | // it will always use the constexpr version of add_with_carry. |
560 | LIBC_INLINE constexpr BigInt operator+(BigInt &&other) const { |
561 | // We use addition commutativity to reuse 'other' and prevent allocation. |
562 | other.add_overflow(*this); // Returned carry value is ignored. |
563 | return other; |
564 | } |
565 | |
566 | LIBC_INLINE constexpr BigInt &operator+=(const BigInt &other) { |
567 | add_overflow(rhs: other); // Returned carry value is ignored. |
568 | return *this; |
569 | } |
570 | |
571 | // Subtract 'rhs' to this number and store the result in this number. |
572 | // Returns the carry value produced by the subtraction operation. |
573 | LIBC_INLINE constexpr WordType sub_overflow(const BigInt &rhs) { |
574 | return multiword::sub_with_borrow(val, rhs.val); |
575 | } |
576 | |
577 | LIBC_INLINE constexpr BigInt operator-(const BigInt &other) const { |
578 | BigInt result = *this; |
579 | result.sub_overflow(other); // Returned carry value is ignored. |
580 | return result; |
581 | } |
582 | |
583 | LIBC_INLINE constexpr BigInt operator-(BigInt &&other) const { |
584 | BigInt result = *this; |
585 | result.sub_overflow(other); // Returned carry value is ignored. |
586 | return result; |
587 | } |
588 | |
589 | LIBC_INLINE constexpr BigInt &operator-=(const BigInt &other) { |
590 | // TODO(lntue): Set overflow flag / errno when carry is true. |
591 | sub_overflow(rhs: other); // Returned carry value is ignored. |
592 | return *this; |
593 | } |
594 | |
595 | // Multiply this number with x and store the result in this number. |
596 | LIBC_INLINE constexpr WordType mul(WordType x) { |
597 | return multiword::scalar_multiply_with_carry(val, x); |
598 | } |
599 | |
600 | // Return the full product. |
601 | template <size_t OtherBits> |
602 | LIBC_INLINE constexpr auto |
603 | ful_mul(const BigInt<OtherBits, Signed, WordType> &other) const { |
604 | BigInt<Bits + OtherBits, Signed, WordType> result; |
605 | multiword::multiply_with_carry(result.val, val, other.val); |
606 | return result; |
607 | } |
608 | |
609 | LIBC_INLINE constexpr BigInt operator*(const BigInt &other) const { |
610 | // Perform full mul and truncate. |
611 | return BigInt(ful_mul(other)); |
612 | } |
613 | |
614 | // Fast hi part of the full product. The normal product `operator*` returns |
615 | // `Bits` least significant bits of the full product, while this function will |
616 | // approximate `Bits` most significant bits of the full product with errors |
617 | // bounded by: |
618 | // 0 <= (a.full_mul(b) >> Bits) - a.quick_mul_hi(b)) <= WORD_COUNT - 1. |
619 | // |
620 | // An example usage of this is to quickly (but less accurately) compute the |
621 | // product of (normalized) mantissas of floating point numbers: |
622 | // (mant_1, mant_2) -> quick_mul_hi -> normalize leading bit |
623 | // is much more efficient than: |
624 | // (mant_1, mant_2) -> ful_mul -> normalize leading bit |
625 | // -> convert back to same Bits width by shifting/rounding, |
626 | // especially for higher precisions. |
627 | // |
628 | // Performance summary: |
629 | // Number of 64-bit x 64-bit -> 128-bit multiplications performed. |
630 | // Bits WORD_COUNT ful_mul quick_mul_hi Error bound |
631 | // 128 2 4 3 1 |
632 | // 196 3 9 6 2 |
633 | // 256 4 16 10 3 |
634 | // 512 8 64 36 7 |
635 | LIBC_INLINE constexpr BigInt quick_mul_hi(const BigInt &other) const { |
636 | BigInt result; |
637 | multiword::quick_mul_hi(result.val, val, other.val); |
638 | return result; |
639 | } |
640 | |
641 | // BigInt(x).pow_n(n) computes x ^ n. |
642 | // Note 0 ^ 0 == 1. |
643 | LIBC_INLINE constexpr void pow_n(uint64_t power) { |
644 | static_assert(!Signed); |
645 | BigInt result = one(); |
646 | BigInt cur_power = *this; |
647 | while (power > 0) { |
648 | if ((power % 2) > 0) |
649 | result *= cur_power; |
650 | power >>= 1; |
651 | cur_power *= cur_power; |
652 | } |
653 | *this = result; |
654 | } |
655 | |
656 | // Performs inplace signed / unsigned division. Returns remainder if not |
657 | // dividing by zero. |
658 | // For signed numbers it behaves like C++ signed integer division. |
659 | // That is by truncating the fractionnal part |
660 | // https://stackoverflow.com/a/3602857 |
661 | LIBC_INLINE constexpr cpp::optional<BigInt> div(const BigInt ÷r) { |
662 | if (LIBC_UNLIKELY(divider.is_zero())) |
663 | return cpp::nullopt; |
664 | if (LIBC_UNLIKELY(divider == BigInt::one())) |
665 | return BigInt::zero(); |
666 | Division result; |
667 | if constexpr (SIGNED) |
668 | result = divide_signed(dividend: *this, divider); |
669 | else |
670 | result = divide_unsigned(dividend: *this, divider); |
671 | *this = result.quotient; |
672 | return result.remainder; |
673 | } |
674 | |
675 | // Efficiently perform BigInt / (x * 2^e), where x is a half-word-size |
676 | // unsigned integer, and return the remainder. The main idea is as follow: |
677 | // Let q = y / (x * 2^e) be the quotient, and |
678 | // r = y % (x * 2^e) be the remainder. |
679 | // First, notice that: |
680 | // r % (2^e) = y % (2^e), |
681 | // so we just need to focus on all the bits of y that is >= 2^e. |
682 | // To speed up the shift-and-add steps, we only use x as the divisor, and |
683 | // performing 32-bit shiftings instead of bit-by-bit shiftings. |
684 | // Since the remainder of each division step < x < 2^(WORD_SIZE / 2), the |
685 | // computation of each step is now properly contained within WordType. |
686 | // And finally we perform some extra alignment steps for the remaining bits. |
687 | LIBC_INLINE constexpr cpp::optional<BigInt> |
688 | div_uint_half_times_pow_2(multiword::half_width_t<WordType> x, size_t e) { |
689 | BigInt remainder; |
690 | if (x == 0) |
691 | return cpp::nullopt; |
692 | if (e >= Bits) { |
693 | remainder = *this; |
694 | *this = BigInt<Bits, false, WordType>(); |
695 | return remainder; |
696 | } |
697 | BigInt quotient; |
698 | WordType x_word = static_cast<WordType>(x); |
699 | constexpr size_t LOG2_WORD_SIZE = |
700 | static_cast<size_t>(cpp::bit_width(value: WORD_SIZE) - 1); |
701 | constexpr size_t HALF_WORD_SIZE = WORD_SIZE >> 1; |
702 | constexpr WordType HALF_MASK = ((WordType(1) << HALF_WORD_SIZE) - 1); |
703 | // lower = smallest multiple of WORD_SIZE that is >= e. |
704 | size_t lower = ((e >> LOG2_WORD_SIZE) + ((e & (WORD_SIZE - 1)) != 0)) |
705 | << LOG2_WORD_SIZE; |
706 | // lower_pos is the index of the closest WORD_SIZE-bit chunk >= 2^e. |
707 | size_t lower_pos = lower / WORD_SIZE; |
708 | // Keep track of current remainder mod x * 2^(32*i) |
709 | WordType rem = 0; |
710 | // pos is the index of the current 64-bit chunk that we are processing. |
711 | size_t pos = WORD_COUNT; |
712 | |
713 | // TODO: look into if constexpr(Bits > 256) skip leading zeroes. |
714 | |
715 | for (size_t q_pos = WORD_COUNT - lower_pos; q_pos > 0; --q_pos) { |
716 | // q_pos is 1 + the index of the current WORD_SIZE-bit chunk of the |
717 | // quotient being processed. Performing the division / modulus with |
718 | // divisor: |
719 | // x * 2^(WORD_SIZE*q_pos - WORD_SIZE/2), |
720 | // i.e. using the upper (WORD_SIZE/2)-bit of the current WORD_SIZE-bit |
721 | // chunk. |
722 | rem <<= HALF_WORD_SIZE; |
723 | rem += val[--pos] >> HALF_WORD_SIZE; |
724 | WordType q_tmp = rem / x_word; |
725 | rem %= x_word; |
726 | |
727 | // Performing the division / modulus with divisor: |
728 | // x * 2^(WORD_SIZE*(q_pos - 1)), |
729 | // i.e. using the lower (WORD_SIZE/2)-bit of the current WORD_SIZE-bit |
730 | // chunk. |
731 | rem <<= HALF_WORD_SIZE; |
732 | rem += val[pos] & HALF_MASK; |
733 | quotient.val[q_pos - 1] = (q_tmp << HALF_WORD_SIZE) + rem / x_word; |
734 | rem %= x_word; |
735 | } |
736 | |
737 | // So far, what we have is: |
738 | // quotient = y / (x * 2^lower), and |
739 | // rem = (y % (x * 2^lower)) / 2^lower. |
740 | // If (lower > e), we will need to perform an extra adjustment of the |
741 | // quotient and remainder, namely: |
742 | // y / (x * 2^e) = [ y / (x * 2^lower) ] * 2^(lower - e) + |
743 | // + (rem * 2^(lower - e)) / x |
744 | // (y % (x * 2^e)) / 2^e = (rem * 2^(lower - e)) % x |
745 | size_t last_shift = lower - e; |
746 | |
747 | if (last_shift > 0) { |
748 | // quotient * 2^(lower - e) |
749 | quotient <<= last_shift; |
750 | WordType q_tmp = 0; |
751 | WordType d = val[--pos]; |
752 | if (last_shift >= HALF_WORD_SIZE) { |
753 | // The shifting (rem * 2^(lower - e)) might overflow WordTyoe, so we |
754 | // perform a HALF_WORD_SIZE-bit shift first. |
755 | rem <<= HALF_WORD_SIZE; |
756 | rem += d >> HALF_WORD_SIZE; |
757 | d &= HALF_MASK; |
758 | q_tmp = rem / x_word; |
759 | rem %= x_word; |
760 | last_shift -= HALF_WORD_SIZE; |
761 | } else { |
762 | // Only use the upper HALF_WORD_SIZE-bit of the current WORD_SIZE-bit |
763 | // chunk. |
764 | d >>= HALF_WORD_SIZE; |
765 | } |
766 | |
767 | if (last_shift > 0) { |
768 | rem <<= HALF_WORD_SIZE; |
769 | rem += d; |
770 | q_tmp <<= last_shift; |
771 | x_word <<= HALF_WORD_SIZE - last_shift; |
772 | q_tmp += rem / x_word; |
773 | rem %= x_word; |
774 | } |
775 | |
776 | quotient.val[0] += q_tmp; |
777 | |
778 | if (lower - e <= HALF_WORD_SIZE) { |
779 | // The remainder rem * 2^(lower - e) might overflow to the higher |
780 | // WORD_SIZE-bit chunk. |
781 | if (pos < WORD_COUNT - 1) { |
782 | remainder[pos + 1] = rem >> HALF_WORD_SIZE; |
783 | } |
784 | remainder[pos] = (rem << HALF_WORD_SIZE) + (val[pos] & HALF_MASK); |
785 | } else { |
786 | remainder[pos] = rem; |
787 | } |
788 | |
789 | } else { |
790 | remainder[pos] = rem; |
791 | } |
792 | |
793 | // Set the remaining lower bits of the remainder. |
794 | for (; pos > 0; --pos) { |
795 | remainder[pos - 1] = val[pos - 1]; |
796 | } |
797 | |
798 | *this = quotient; |
799 | return remainder; |
800 | } |
801 | |
802 | LIBC_INLINE constexpr BigInt operator/(const BigInt &other) const { |
803 | BigInt result(*this); |
804 | result.div(other); |
805 | return result; |
806 | } |
807 | |
808 | LIBC_INLINE constexpr BigInt &operator/=(const BigInt &other) { |
809 | div(divider: other); |
810 | return *this; |
811 | } |
812 | |
813 | LIBC_INLINE constexpr BigInt operator%(const BigInt &other) const { |
814 | BigInt result(*this); |
815 | return *result.div(other); |
816 | } |
817 | |
818 | LIBC_INLINE constexpr BigInt operator%=(const BigInt &other) { |
819 | *this = *this % other; |
820 | return *this; |
821 | } |
822 | |
823 | LIBC_INLINE constexpr BigInt &operator*=(const BigInt &other) { |
824 | *this = *this * other; |
825 | return *this; |
826 | } |
827 | |
828 | LIBC_INLINE constexpr BigInt &operator<<=(size_t s) { |
829 | val = multiword::shift<multiword::LEFT, SIGNED>(val, s); |
830 | return *this; |
831 | } |
832 | |
833 | LIBC_INLINE constexpr BigInt operator<<(size_t s) const { |
834 | return BigInt(multiword::shift<multiword::LEFT, SIGNED>(val, s)); |
835 | } |
836 | |
837 | LIBC_INLINE constexpr BigInt &operator>>=(size_t s) { |
838 | val = multiword::shift<multiword::RIGHT, SIGNED>(val, s); |
839 | return *this; |
840 | } |
841 | |
842 | LIBC_INLINE constexpr BigInt operator>>(size_t s) const { |
843 | return BigInt(multiword::shift<multiword::RIGHT, SIGNED>(val, s)); |
844 | } |
845 | |
846 | #define DEFINE_BINOP(OP) \ |
847 | LIBC_INLINE friend constexpr BigInt operator OP(const BigInt &lhs, \ |
848 | const BigInt &rhs) { \ |
849 | BigInt result; \ |
850 | for (size_t i = 0; i < WORD_COUNT; ++i) \ |
851 | result[i] = lhs[i] OP rhs[i]; \ |
852 | return result; \ |
853 | } \ |
854 | LIBC_INLINE friend constexpr BigInt operator OP##=(BigInt &lhs, \ |
855 | const BigInt &rhs) { \ |
856 | for (size_t i = 0; i < WORD_COUNT; ++i) \ |
857 | lhs[i] OP## = rhs[i]; \ |
858 | return lhs; \ |
859 | } |
860 | |
861 | DEFINE_BINOP(&) // & and &= |
862 | DEFINE_BINOP(|) // | and |= |
863 | DEFINE_BINOP(^) // ^ and ^= |
864 | #undef DEFINE_BINOP |
865 | |
866 | LIBC_INLINE constexpr BigInt operator~() const { |
867 | BigInt result; |
868 | for (size_t i = 0; i < WORD_COUNT; ++i) |
869 | result[i] = static_cast<WordType>(~val[i]); |
870 | return result; |
871 | } |
872 | |
873 | LIBC_INLINE constexpr BigInt operator-() const { |
874 | BigInt result(*this); |
875 | result.negate(); |
876 | return result; |
877 | } |
878 | |
879 | LIBC_INLINE friend constexpr bool operator==(const BigInt &lhs, |
880 | const BigInt &rhs) { |
881 | for (size_t i = 0; i < WORD_COUNT; ++i) |
882 | if (lhs.val[i] != rhs.val[i]) |
883 | return false; |
884 | return true; |
885 | } |
886 | |
887 | LIBC_INLINE friend constexpr bool operator!=(const BigInt &lhs, |
888 | const BigInt &rhs) { |
889 | return !(lhs == rhs); |
890 | } |
891 | |
892 | LIBC_INLINE friend constexpr bool operator>(const BigInt &lhs, |
893 | const BigInt &rhs) { |
894 | return cmp(lhs, rhs) > 0; |
895 | } |
896 | LIBC_INLINE friend constexpr bool operator>=(const BigInt &lhs, |
897 | const BigInt &rhs) { |
898 | return cmp(lhs, rhs) >= 0; |
899 | } |
900 | LIBC_INLINE friend constexpr bool operator<(const BigInt &lhs, |
901 | const BigInt &rhs) { |
902 | return cmp(lhs, rhs) < 0; |
903 | } |
904 | LIBC_INLINE friend constexpr bool operator<=(const BigInt &lhs, |
905 | const BigInt &rhs) { |
906 | return cmp(lhs, rhs) <= 0; |
907 | } |
908 | |
909 | LIBC_INLINE constexpr BigInt &operator++() { |
910 | increment(); |
911 | return *this; |
912 | } |
913 | |
914 | LIBC_INLINE constexpr BigInt operator++(int) { |
915 | BigInt oldval(*this); |
916 | increment(); |
917 | return oldval; |
918 | } |
919 | |
920 | LIBC_INLINE constexpr BigInt &operator--() { |
921 | decrement(); |
922 | return *this; |
923 | } |
924 | |
925 | LIBC_INLINE constexpr BigInt operator--(int) { |
926 | BigInt oldval(*this); |
927 | decrement(); |
928 | return oldval; |
929 | } |
930 | |
931 | // Return the i-th word of the number. |
932 | LIBC_INLINE constexpr const WordType &operator[](size_t i) const { |
933 | return val[i]; |
934 | } |
935 | |
936 | // Return the i-th word of the number. |
937 | LIBC_INLINE constexpr WordType &operator[](size_t i) { return val[i]; } |
938 | |
939 | // Return the i-th bit of the number. |
940 | LIBC_INLINE constexpr bool get_bit(size_t i) const { |
941 | const size_t word_index = i / WORD_SIZE; |
942 | return 1 & (val[word_index] >> (i % WORD_SIZE)); |
943 | } |
944 | |
945 | // Set the i-th bit of the number. |
946 | LIBC_INLINE constexpr void set_bit(size_t i) { |
947 | const size_t word_index = i / WORD_SIZE; |
948 | val[word_index] |= WordType(1) << (i % WORD_SIZE); |
949 | } |
950 | |
951 | private: |
952 | LIBC_INLINE friend constexpr int cmp(const BigInt &lhs, const BigInt &rhs) { |
953 | constexpr auto compare = [](WordType a, WordType b) { |
954 | return a == b ? 0 : a > b ? 1 : -1; |
955 | }; |
956 | if constexpr (Signed) { |
957 | const bool lhs_is_neg = lhs.is_neg(); |
958 | const bool rhs_is_neg = rhs.is_neg(); |
959 | if (lhs_is_neg != rhs_is_neg) |
960 | return rhs_is_neg ? 1 : -1; |
961 | } |
962 | for (size_t i = WORD_COUNT; i-- > 0;) |
963 | if (auto cmp = compare(lhs[i], rhs[i]); cmp != 0) |
964 | return cmp; |
965 | return 0; |
966 | } |
967 | |
968 | LIBC_INLINE constexpr void bitwise_not() { |
969 | for (auto &part : val) |
970 | part = static_cast<WordType>(~part); |
971 | } |
972 | |
973 | LIBC_INLINE constexpr void negate() { |
974 | bitwise_not(); |
975 | increment(); |
976 | } |
977 | |
978 | LIBC_INLINE constexpr void increment() { |
979 | multiword::add_with_carry(val, cpp::array<WordType, 1>{1}); |
980 | } |
981 | |
982 | LIBC_INLINE constexpr void decrement() { |
983 | multiword::sub_with_borrow(val, cpp::array<WordType, 1>{1}); |
984 | } |
985 | |
986 | LIBC_INLINE constexpr void extend(size_t index, bool is_neg) { |
987 | const WordType value = is_neg ? cpp::numeric_limits<WordType>::max() |
988 | : cpp::numeric_limits<WordType>::min(); |
989 | for (size_t i = index; i < WORD_COUNT; ++i) |
990 | val[i] = value; |
991 | } |
992 | |
993 | LIBC_INLINE constexpr bool get_msb() const { |
994 | return val.back() >> (WORD_SIZE - 1); |
995 | } |
996 | |
997 | LIBC_INLINE constexpr void set_msb() { |
998 | val.back() |= mask_leading_ones<WordType, 1>(); |
999 | } |
1000 | |
1001 | LIBC_INLINE constexpr void clear_msb() { |
1002 | val.back() &= mask_trailing_ones<WordType, WORD_SIZE - 1>(); |
1003 | } |
1004 | LIBC_INLINE constexpr static Division divide_unsigned(const BigInt ÷nd, |
1005 | const BigInt ÷r) { |
1006 | BigInt remainder = dividend; |
1007 | BigInt quotient; |
1008 | if (remainder >= divider) { |
1009 | BigInt subtractor = divider; |
1010 | int cur_bit = multiword::countl_zero(subtractor.val) - |
1011 | multiword::countl_zero(remainder.val); |
1012 | subtractor <<= static_cast<size_t>(cur_bit); |
1013 | for (; cur_bit >= 0 && remainder > 0; --cur_bit, subtractor >>= 1) { |
1014 | if (remainder < subtractor) |
1015 | continue; |
1016 | remainder -= subtractor; |
1017 | quotient.set_bit(static_cast<size_t>(cur_bit)); |
1018 | } |
1019 | } |
1020 | return Division{quotient, remainder}; |
1021 | } |
1022 | |
1023 | LIBC_INLINE constexpr static Division divide_signed(const BigInt ÷nd, |
1024 | const BigInt ÷r) { |
1025 | // Special case because it is not possible to negate the min value of a |
1026 | // signed integer. |
1027 | if (dividend == min() && divider == min()) |
1028 | return Division{one(), zero()}; |
1029 | // 1. Convert the dividend and divisor to unsigned representation. |
1030 | unsigned_type udividend(dividend); |
1031 | unsigned_type udivider(divider); |
1032 | // 2. Negate the dividend if it's negative, and similarly for the divisor. |
1033 | const bool dividend_is_neg = dividend.is_neg(); |
1034 | const bool divider_is_neg = divider.is_neg(); |
1035 | if (dividend_is_neg) |
1036 | udividend.negate(); |
1037 | if (divider_is_neg) |
1038 | udivider.negate(); |
1039 | // 3. Use unsigned multiword division algorithm. |
1040 | const auto unsigned_result = divide_unsigned(dividend: udividend, divider: udivider); |
1041 | // 4. Convert the quotient and remainder to signed representation. |
1042 | Division result; |
1043 | result.quotient = signed_type(unsigned_result.quotient); |
1044 | result.remainder = signed_type(unsigned_result.remainder); |
1045 | // 5. Negate the quotient if the dividend and divisor had opposite signs. |
1046 | if (dividend_is_neg != divider_is_neg) |
1047 | result.quotient.negate(); |
1048 | // 6. Negate the remainder if the dividend was negative. |
1049 | if (dividend_is_neg) |
1050 | result.remainder.negate(); |
1051 | return result; |
1052 | } |
1053 | |
1054 | friend signed_type; |
1055 | friend unsigned_type; |
1056 | }; |
1057 | |
1058 | namespace internal { |
1059 | // We default BigInt's WordType to 'uint64_t' or 'uint32_t' depending on type |
1060 | // availability. |
1061 | template <size_t Bits> |
1062 | struct WordTypeSelector : cpp::type_identity< |
1063 | #ifdef LIBC_TYPES_HAS_INT64 |
1064 | uint64_t |
1065 | #else |
1066 | uint32_t |
1067 | #endif // LIBC_TYPES_HAS_INT64 |
1068 | > { |
1069 | }; |
1070 | // Except if we request 16 or 32 bits explicitly. |
1071 | template <> struct WordTypeSelector<16> : cpp::type_identity<uint16_t> {}; |
1072 | template <> struct WordTypeSelector<32> : cpp::type_identity<uint32_t> {}; |
1073 | template <> struct WordTypeSelector<96> : cpp::type_identity<uint32_t> {}; |
1074 | |
1075 | template <size_t Bits> |
1076 | using WordTypeSelectorT = typename WordTypeSelector<Bits>::type; |
1077 | } // namespace internal |
1078 | |
1079 | template <size_t Bits> |
1080 | using UInt = BigInt<Bits, false, internal::WordTypeSelectorT<Bits>>; |
1081 | |
1082 | template <size_t Bits> |
1083 | using Int = BigInt<Bits, true, internal::WordTypeSelectorT<Bits>>; |
1084 | |
1085 | // Provides limits of BigInt. |
1086 | template <size_t Bits, bool Signed, typename T> |
1087 | struct cpp::numeric_limits<BigInt<Bits, Signed, T>> { |
1088 | LIBC_INLINE static constexpr BigInt<Bits, Signed, T> max() { |
1089 | return BigInt<Bits, Signed, T>::max(); |
1090 | } |
1091 | LIBC_INLINE static constexpr BigInt<Bits, Signed, T> min() { |
1092 | return BigInt<Bits, Signed, T>::min(); |
1093 | } |
1094 | // Meant to match std::numeric_limits interface. |
1095 | // NOLINTNEXTLINE(readability-identifier-naming) |
1096 | LIBC_INLINE_VAR static constexpr int digits = Bits - Signed; |
1097 | }; |
1098 | |
1099 | // type traits to determine whether a T is a BigInt. |
1100 | template <typename T> struct is_big_int : cpp::false_type {}; |
1101 | |
1102 | template <size_t Bits, bool Signed, typename T> |
1103 | struct is_big_int<BigInt<Bits, Signed, T>> : cpp::true_type {}; |
1104 | |
1105 | template <class T> |
1106 | LIBC_INLINE_VAR constexpr bool is_big_int_v = is_big_int<T>::value; |
1107 | |
1108 | // extensions of type traits to include BigInt |
1109 | |
1110 | // is_integral_or_big_int |
1111 | template <typename T> |
1112 | struct is_integral_or_big_int |
1113 | : cpp::bool_constant<(cpp::is_integral_v<T> || is_big_int_v<T>)> {}; |
1114 | |
1115 | template <typename T> |
1116 | LIBC_INLINE_VAR constexpr bool is_integral_or_big_int_v = |
1117 | is_integral_or_big_int<T>::value; |
1118 | |
1119 | // make_big_int_unsigned |
1120 | template <typename T> struct make_big_int_unsigned; |
1121 | |
1122 | template <size_t Bits, bool Signed, typename T> |
1123 | struct make_big_int_unsigned<BigInt<Bits, Signed, T>> |
1124 | : cpp::type_identity<BigInt<Bits, false, T>> {}; |
1125 | |
1126 | template <typename T> |
1127 | using make_big_int_unsigned_t = typename make_big_int_unsigned<T>::type; |
1128 | |
1129 | // make_big_int_signed |
1130 | template <typename T> struct make_big_int_signed; |
1131 | |
1132 | template <size_t Bits, bool Signed, typename T> |
1133 | struct make_big_int_signed<BigInt<Bits, Signed, T>> |
1134 | : cpp::type_identity<BigInt<Bits, true, T>> {}; |
1135 | |
1136 | template <typename T> |
1137 | using make_big_int_signed_t = typename make_big_int_signed<T>::type; |
1138 | |
1139 | // make_integral_or_big_int_unsigned |
1140 | template <typename T, class = void> struct make_integral_or_big_int_unsigned; |
1141 | |
1142 | template <typename T> |
1143 | struct make_integral_or_big_int_unsigned< |
1144 | T, cpp::enable_if_t<cpp::is_integral_v<T>>> : cpp::make_unsigned<T> {}; |
1145 | |
1146 | template <typename T> |
1147 | struct make_integral_or_big_int_unsigned<T, cpp::enable_if_t<is_big_int_v<T>>> |
1148 | : make_big_int_unsigned<T> {}; |
1149 | |
1150 | template <typename T> |
1151 | using make_integral_or_big_int_unsigned_t = |
1152 | typename make_integral_or_big_int_unsigned<T>::type; |
1153 | |
1154 | // make_integral_or_big_int_signed |
1155 | template <typename T, class = void> struct make_integral_or_big_int_signed; |
1156 | |
1157 | template <typename T> |
1158 | struct make_integral_or_big_int_signed<T, |
1159 | cpp::enable_if_t<cpp::is_integral_v<T>>> |
1160 | : cpp::make_signed<T> {}; |
1161 | |
1162 | template <typename T> |
1163 | struct make_integral_or_big_int_signed<T, cpp::enable_if_t<is_big_int_v<T>>> |
1164 | : make_big_int_signed<T> {}; |
1165 | |
1166 | template <typename T> |
1167 | using make_integral_or_big_int_signed_t = |
1168 | typename make_integral_or_big_int_signed<T>::type; |
1169 | |
1170 | // is_unsigned_integral_or_big_int |
1171 | template <typename T> |
1172 | struct is_unsigned_integral_or_big_int |
1173 | : cpp::bool_constant< |
1174 | cpp::is_same_v<T, make_integral_or_big_int_unsigned_t<T>>> {}; |
1175 | |
1176 | template <typename T> |
1177 | // Meant to look like <type_traits> helper variable templates. |
1178 | // NOLINTNEXTLINE(readability-identifier-naming) |
1179 | LIBC_INLINE_VAR constexpr bool is_unsigned_integral_or_big_int_v = |
1180 | is_unsigned_integral_or_big_int<T>::value; |
1181 | |
1182 | namespace cpp { |
1183 | |
1184 | // Specialization of cpp::bit_cast ('bit.h') from T to BigInt. |
1185 | template <typename To, typename From> |
1186 | LIBC_INLINE constexpr cpp::enable_if_t< |
1187 | (sizeof(To) == sizeof(From)) && cpp::is_trivially_copyable<To>::value && |
1188 | cpp::is_trivially_copyable<From>::value && is_big_int<To>::value, |
1189 | To> |
1190 | bit_cast(const From &from) { |
1191 | To out; |
1192 | using Storage = decltype(out.val); |
1193 | out.val = cpp::bit_cast<Storage>(from); |
1194 | return out; |
1195 | } |
1196 | |
1197 | // Specialization of cpp::bit_cast ('bit.h') from BigInt to T. |
1198 | template <typename To, size_t Bits> |
1199 | LIBC_INLINE constexpr cpp::enable_if_t< |
1200 | sizeof(To) == sizeof(UInt<Bits>) && |
1201 | cpp::is_trivially_constructible<To>::value && |
1202 | cpp::is_trivially_copyable<To>::value && |
1203 | cpp::is_trivially_copyable<UInt<Bits>>::value, |
1204 | To> |
1205 | bit_cast(const UInt<Bits> &from) { |
1206 | return cpp::bit_cast<To>(from.val); |
1207 | } |
1208 | |
1209 | // Specialization of cpp::popcount ('bit.h') for BigInt. |
1210 | template <typename T> |
1211 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
1212 | popcount(T value) { |
1213 | int bits = 0; |
1214 | for (auto word : value.val) |
1215 | if (word) |
1216 | bits += popcount(word); |
1217 | return bits; |
1218 | } |
1219 | |
1220 | // Specialization of cpp::has_single_bit ('bit.h') for BigInt. |
1221 | template <typename T> |
1222 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, bool> |
1223 | has_single_bit(T value) { |
1224 | int bits = 0; |
1225 | for (auto word : value.val) { |
1226 | if (word == 0) |
1227 | continue; |
1228 | bits += popcount(word); |
1229 | if (bits > 1) |
1230 | return false; |
1231 | } |
1232 | return bits == 1; |
1233 | } |
1234 | |
1235 | // Specialization of cpp::countr_zero ('bit.h') for BigInt. |
1236 | template <typename T> |
1237 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
1238 | countr_zero(const T &value) { |
1239 | return multiword::countr_zero(value.val); |
1240 | } |
1241 | |
1242 | // Specialization of cpp::countl_zero ('bit.h') for BigInt. |
1243 | template <typename T> |
1244 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
1245 | countl_zero(const T &value) { |
1246 | return multiword::countl_zero(value.val); |
1247 | } |
1248 | |
1249 | // Specialization of cpp::countl_one ('bit.h') for BigInt. |
1250 | template <typename T> |
1251 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
1252 | countl_one(T value) { |
1253 | return multiword::countl_one(value.val); |
1254 | } |
1255 | |
1256 | // Specialization of cpp::countr_one ('bit.h') for BigInt. |
1257 | template <typename T> |
1258 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
1259 | countr_one(T value) { |
1260 | return multiword::countr_one(value.val); |
1261 | } |
1262 | |
1263 | // Specialization of cpp::bit_width ('bit.h') for BigInt. |
1264 | template <typename T> |
1265 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
1266 | bit_width(T value) { |
1267 | return cpp::numeric_limits<T>::digits - cpp::countl_zero(value); |
1268 | } |
1269 | |
1270 | // Forward-declare rotr so that rotl can use it. |
1271 | template <typename T> |
1272 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> |
1273 | rotr(T value, int rotate); |
1274 | |
1275 | // Specialization of cpp::rotl ('bit.h') for BigInt. |
1276 | template <typename T> |
1277 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> |
1278 | rotl(T value, int rotate) { |
1279 | constexpr int N = cpp::numeric_limits<T>::digits; |
1280 | rotate = rotate % N; |
1281 | if (!rotate) |
1282 | return value; |
1283 | if (rotate < 0) |
1284 | return cpp::rotr<T>(value, -rotate); |
1285 | return (value << static_cast<size_t>(rotate)) | |
1286 | (value >> (N - static_cast<size_t>(rotate))); |
1287 | } |
1288 | |
1289 | // Specialization of cpp::rotr ('bit.h') for BigInt. |
1290 | template <typename T> |
1291 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> |
1292 | rotr(T value, int rotate) { |
1293 | constexpr int N = cpp::numeric_limits<T>::digits; |
1294 | rotate = rotate % N; |
1295 | if (!rotate) |
1296 | return value; |
1297 | if (rotate < 0) |
1298 | return cpp::rotl<T>(value, -rotate); |
1299 | return (value >> static_cast<size_t>(rotate)) | |
1300 | (value << (N - static_cast<size_t>(rotate))); |
1301 | } |
1302 | |
1303 | } // namespace cpp |
1304 | |
1305 | // Specialization of mask_trailing_ones ('math_extras.h') for BigInt. |
1306 | template <typename T, size_t count> |
1307 | LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> |
1308 | mask_trailing_ones() { |
1309 | static_assert(!T::SIGNED && count <= T::BITS); |
1310 | if (count == T::BITS) |
1311 | return T::all_ones(); |
1312 | constexpr size_t QUOTIENT = count / T::WORD_SIZE; |
1313 | constexpr size_t REMAINDER = count % T::WORD_SIZE; |
1314 | T out; // zero initialized |
1315 | for (size_t i = 0; i <= QUOTIENT; ++i) |
1316 | out[i] = i < QUOTIENT |
1317 | ? cpp::numeric_limits<typename T::word_type>::max() |
1318 | : mask_trailing_ones<typename T::word_type, REMAINDER>(); |
1319 | return out; |
1320 | } |
1321 | |
1322 | // Specialization of mask_leading_ones ('math_extras.h') for BigInt. |
1323 | template <typename T, size_t count> |
1324 | LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> mask_leading_ones() { |
1325 | static_assert(!T::SIGNED && count <= T::BITS); |
1326 | if (count == T::BITS) |
1327 | return T::all_ones(); |
1328 | constexpr size_t QUOTIENT = (T::BITS - count - 1U) / T::WORD_SIZE; |
1329 | constexpr size_t REMAINDER = count % T::WORD_SIZE; |
1330 | T out; // zero initialized |
1331 | for (size_t i = QUOTIENT; i < T::WORD_COUNT; ++i) |
1332 | out[i] = i > QUOTIENT |
1333 | ? cpp::numeric_limits<typename T::word_type>::max() |
1334 | : mask_leading_ones<typename T::word_type, REMAINDER>(); |
1335 | return out; |
1336 | } |
1337 | |
1338 | // Specialization of mask_trailing_zeros ('math_extras.h') for BigInt. |
1339 | template <typename T, size_t count> |
1340 | LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> |
1341 | mask_trailing_zeros() { |
1342 | return mask_leading_ones<T, T::BITS - count>(); |
1343 | } |
1344 | |
1345 | // Specialization of mask_leading_zeros ('math_extras.h') for BigInt. |
1346 | template <typename T, size_t count> |
1347 | LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> |
1348 | mask_leading_zeros() { |
1349 | return mask_trailing_ones<T, T::BITS - count>(); |
1350 | } |
1351 | |
1352 | // Specialization of count_zeros ('math_extras.h') for BigInt. |
1353 | template <typename T> |
1354 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
1355 | count_zeros(T value) { |
1356 | return cpp::popcount(~value); |
1357 | } |
1358 | |
1359 | // Specialization of first_leading_zero ('math_extras.h') for BigInt. |
1360 | template <typename T> |
1361 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
1362 | first_leading_zero(T value) { |
1363 | return value == cpp::numeric_limits<T>::max() ? 0 |
1364 | : cpp::countl_one(value) + 1; |
1365 | } |
1366 | |
1367 | // Specialization of first_leading_one ('math_extras.h') for BigInt. |
1368 | template <typename T> |
1369 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
1370 | first_leading_one(T value) { |
1371 | return first_leading_zero(~value); |
1372 | } |
1373 | |
1374 | // Specialization of first_trailing_zero ('math_extras.h') for BigInt. |
1375 | template <typename T> |
1376 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
1377 | first_trailing_zero(T value) { |
1378 | return value == cpp::numeric_limits<T>::max() ? 0 |
1379 | : cpp::countr_zero(~value) + 1; |
1380 | } |
1381 | |
1382 | // Specialization of first_trailing_one ('math_extras.h') for BigInt. |
1383 | template <typename T> |
1384 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
1385 | first_trailing_one(T value) { |
1386 | return value == 0 ? 0 : cpp::countr_zero(value) + 1; |
1387 | } |
1388 | |
1389 | } // namespace LIBC_NAMESPACE_DECL |
1390 | |
1391 | #endif // LLVM_LIBC_SRC___SUPPORT_BIG_INT_H |
1392 | |