1 //===-- A class to manipulate wide integers. --------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_SRC___SUPPORT_BIG_INT_H
10 #define LLVM_LIBC_SRC___SUPPORT_BIG_INT_H
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"
25 #include <stddef.h> // For size_t
28 namespace LIBC_NAMESPACE_DECL
{
32 // A type trait mapping unsigned integers to their half-width unsigned
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
;
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>;
49 LIBC_INLINE
constexpr DoubleWide(T lo
, T hi
) : UP({lo
, hi
}) {}
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
>(
58 half_type(value
>> cpp::numeric_limits
<half_type
>::digits
));
61 // The low part of a DoubleWide value.
62 template <typename T
> LIBC_INLINE
constexpr T
lo(const DoubleWide
<T
> &value
) {
65 // The high part of a DoubleWide value.
66 template <typename T
> LIBC_INLINE
constexpr T
hi(const DoubleWide
<T
> &value
) {
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
));
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
));
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>(uint16_t(a
) * uint16_t(b
));
83 } else if constexpr (cpp::is_same_v
<word
, uint16_t>) {
84 return split
<uint32_t>(uint32_t(a
) * uint32_t(b
));
86 #ifdef LIBC_TYPES_HAS_INT64
87 else if constexpr (cpp::is_same_v
<word
, uint32_t>) {
88 return split
<uint64_t>(uint64_t(a
) * uint64_t(b
));
91 #ifdef LIBC_TYPES_HAS_INT128
92 else if constexpr (cpp::is_same_v
<word
, uint64_t>) {
93 return split
<__uint128_t
>(__uint128_t(a
) * __uint128_t(b
));
97 using half_word
= half_width_t
<word
>;
98 const auto shiftl
= [](word value
) -> word
{
99 return value
<< cpp::numeric_limits
<half_word
>::digits
;
101 const auto shiftr
= [](word value
) -> word
{
102 return value
>> cpp::numeric_limits
<half_word
>::digits
;
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.
109 // x b => x b_hi b_lo
112 // We convert 'lo' and 'hi' from 'half_word' to 'word' so multiplication
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;
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
);
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
);
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)
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
);
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
);
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
,
173 return add_with_carry(dst
, mul2(b
, c
));
176 // An array of two elements serving as an accumulator during multiword
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
;
187 LIBC_INLINE
constexpr T
sum() const { return UP::front(); }
188 LIBC_INLINE
constexpr T
carry() const { return UP::back(); }
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
,
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
);
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;
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
);
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
;
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
) {
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();
240 dst
.back() = acc
.carry();
243 template <typename word
, size_t N
>
244 LIBC_INLINE
constexpr bool is_negative(cpp::array
<word
, N
> &array
) {
245 using signed_word
= cpp::make_signed_t
<word
>;
246 return cpp::bit_cast
<signed_word
>(array
.back()) < 0;
249 // An enum for the shift function below.
250 enum Direction
{ LEFT
, RIGHT
};
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
,
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
)
269 return cpp::bit_cast
<cpp::array
<word
, N
>>(tmp
);
272 if (LIBC_UNLIKELY(offset
== 0))
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;
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
);
287 return is_neg
? -1 : 0;
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
);
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
[at(index
)];
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
)));
306 dst
= static_cast<word
>((part1
>> bit_offset
) |
307 (part2
<< (WORD_BITS
- bit_offset
)));
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) { \
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) \
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
330 } // namespace multiword
332 template <size_t Bits
, bool Signed
, typename WordType
= uint64_t>
335 static_assert(cpp::is_integral_v
<WordType
> && cpp::is_unsigned_v
<WordType
>,
336 "WordType must be unsigned integer.");
344 using word_type
= WordType
;
345 using unsigned_type
= BigInt
<Bits
, false, word_type
>;
346 using signed_type
= BigInt
<Bits
, true, word_type
>;
348 LIBC_INLINE_VAR
static constexpr bool SIGNED
= Signed
;
349 LIBC_INLINE_VAR
static constexpr size_t BITS
= Bits
;
351 static constexpr size_t WORD_SIZE
= sizeof(WordType
) * CHAR_BIT
;
353 static_assert(Bits
> 0 && Bits
% WORD_SIZE
== 0,
354 "Number of bits in BigInt should be a multiple of WORD_SIZE.");
356 LIBC_INLINE_VAR
static constexpr size_t WORD_COUNT
= Bits
/ WORD_SIZE
;
358 cpp::array
<WordType
, WORD_COUNT
> val
{}; // zero initialized.
360 LIBC_INLINE
constexpr BigInt() = default;
362 LIBC_INLINE
constexpr BigInt(const BigInt
&other
) = default;
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();
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.");
374 if constexpr (BigIntOther::WORD_SIZE
< WORD_SIZE
) {
375 // OtherWordType is smaller
376 constexpr size_t WORD_SIZE_RATIO
= WORD_SIZE
/ BigIntOther::WORD_SIZE
;
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
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
);
391 } else { // zero or sign extend
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
;
405 // Pretend there are extra words of the correct sign extension as needed
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
));
414 // Copy the last word into place.
415 val
[(i
/ WORD_SIZE_RATIO
)] = cur_word
;
416 extend((i
/ WORD_SIZE_RATIO
) + 1, should_sign_extend
);
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
)
422 } else { // zero or sign extend
424 for (; i
< BigIntOther::WORD_COUNT
; ++i
)
426 extend(i
, should_sign_extend
);
429 // OtherWordType is bigger.
430 constexpr size_t WORD_SIZE_RATIO
= BigIntOther::WORD_SIZE
/ WORD_SIZE
;
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
));
441 } else { // zero or sign extend
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
));
450 extend(i
* WORD_SIZE_RATIO
, should_sign_extend
);
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
)
462 LIBC_INLINE
constexpr explicit BigInt(
463 const cpp::array
<WordType
, WORD_COUNT
> &words
) {
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 !cpp::is_same_v
<T
, bool>>>
470 LIBC_INLINE
constexpr BigInt(T v
) {
471 constexpr size_t T_SIZE
= sizeof(T
) * CHAR_BIT
;
472 const bool is_neg
= v
< 0;
473 for (size_t i
= 0; i
< WORD_COUNT
; ++i
) {
478 val
[i
] = static_cast<WordType
>(v
);
479 if constexpr (T_SIZE
> WORD_SIZE
)
485 LIBC_INLINE
constexpr BigInt
&operator=(const BigInt
&other
) = default;
488 LIBC_INLINE
static constexpr BigInt
zero() { return BigInt(); }
489 LIBC_INLINE
static constexpr BigInt
one() { return BigInt(1); }
490 LIBC_INLINE
static constexpr BigInt
all_ones() { return ~zero(); }
491 LIBC_INLINE
static constexpr BigInt
min() {
493 if constexpr (SIGNED
)
497 LIBC_INLINE
static constexpr BigInt
max() {
498 BigInt out
= all_ones();
499 if constexpr (SIGNED
)
504 // TODO: Reuse the Sign type.
505 LIBC_INLINE
constexpr bool is_neg() const { return SIGNED
&& get_msb(); }
507 template <size_t OtherBits
, bool OtherSigned
, typename OtherWordType
>
508 LIBC_INLINE
constexpr explicit
509 operator BigInt
<OtherBits
, OtherSigned
, OtherWordType
>() const {
510 return BigInt
<OtherBits
, OtherSigned
, OtherWordType
>(this);
513 template <typename T
> LIBC_INLINE
constexpr explicit operator T() const {
517 template <typename T
>
518 LIBC_INLINE
constexpr cpp::enable_if_t
<
519 cpp::is_integral_v
<T
> && !cpp::is_same_v
<T
, bool>, T
>
521 constexpr size_t T_SIZE
= sizeof(T
) * CHAR_BIT
;
522 T lo
= static_cast<T
>(val
[0]);
523 if constexpr (T_SIZE
<= WORD_SIZE
)
525 constexpr size_t MAX_COUNT
=
526 T_SIZE
> Bits
? WORD_COUNT
: T_SIZE
/ WORD_SIZE
;
527 for (size_t i
= 1; i
< MAX_COUNT
; ++i
)
528 lo
+= static_cast<T
>(static_cast<T
>(val
[i
]) << (WORD_SIZE
* i
));
529 if constexpr (Signed
&& (T_SIZE
> Bits
)) {
530 // Extend sign for negative numbers.
531 constexpr T MASK
= (~T(0) << Bits
);
538 LIBC_INLINE
constexpr explicit operator bool() const { return !is_zero(); }
540 LIBC_INLINE
constexpr bool is_zero() const {
541 for (auto part
: val
)
547 // Add 'rhs' to this number and store the result in this number.
548 // Returns the carry value produced by the addition operation.
549 LIBC_INLINE
constexpr WordType
add_overflow(const BigInt
&rhs
) {
550 return multiword::add_with_carry(val
, rhs
.val
);
553 LIBC_INLINE
constexpr BigInt
operator+(const BigInt
&other
) const {
554 BigInt result
= *this;
555 result
.add_overflow(other
);
559 // This will only apply when initializing a variable from constant values, so
560 // it will always use the constexpr version of add_with_carry.
561 LIBC_INLINE
constexpr BigInt
operator+(BigInt
&&other
) const {
562 // We use addition commutativity to reuse 'other' and prevent allocation.
563 other
.add_overflow(*this); // Returned carry value is ignored.
567 LIBC_INLINE
constexpr BigInt
&operator+=(const BigInt
&other
) {
568 add_overflow(other
); // Returned carry value is ignored.
572 // Subtract 'rhs' to this number and store the result in this number.
573 // Returns the carry value produced by the subtraction operation.
574 LIBC_INLINE
constexpr WordType
sub_overflow(const BigInt
&rhs
) {
575 return multiword::sub_with_borrow(val
, rhs
.val
);
578 LIBC_INLINE
constexpr BigInt
operator-(const BigInt
&other
) const {
579 BigInt result
= *this;
580 result
.sub_overflow(other
); // Returned carry value is ignored.
584 LIBC_INLINE
constexpr BigInt
operator-(BigInt
&&other
) const {
585 BigInt result
= *this;
586 result
.sub_overflow(other
); // Returned carry value is ignored.
590 LIBC_INLINE
constexpr BigInt
&operator-=(const BigInt
&other
) {
591 // TODO(lntue): Set overflow flag / errno when carry is true.
592 sub_overflow(other
); // Returned carry value is ignored.
596 // Multiply this number with x and store the result in this number.
597 LIBC_INLINE
constexpr WordType
mul(WordType x
) {
598 return multiword::scalar_multiply_with_carry(val
, x
);
601 // Return the full product.
602 template <size_t OtherBits
>
603 LIBC_INLINE
constexpr auto
604 ful_mul(const BigInt
<OtherBits
, Signed
, WordType
> &other
) const {
605 BigInt
<Bits
+ OtherBits
, Signed
, WordType
> result
;
606 multiword::multiply_with_carry(result
.val
, val
, other
.val
);
610 LIBC_INLINE
constexpr BigInt
operator*(const BigInt
&other
) const {
611 // Perform full mul and truncate.
612 return BigInt(ful_mul(other
));
615 // Fast hi part of the full product. The normal product `operator*` returns
616 // `Bits` least significant bits of the full product, while this function will
617 // approximate `Bits` most significant bits of the full product with errors
619 // 0 <= (a.full_mul(b) >> Bits) - a.quick_mul_hi(b)) <= WORD_COUNT - 1.
621 // An example usage of this is to quickly (but less accurately) compute the
622 // product of (normalized) mantissas of floating point numbers:
623 // (mant_1, mant_2) -> quick_mul_hi -> normalize leading bit
624 // is much more efficient than:
625 // (mant_1, mant_2) -> ful_mul -> normalize leading bit
626 // -> convert back to same Bits width by shifting/rounding,
627 // especially for higher precisions.
629 // Performance summary:
630 // Number of 64-bit x 64-bit -> 128-bit multiplications performed.
631 // Bits WORD_COUNT ful_mul quick_mul_hi Error bound
636 LIBC_INLINE
constexpr BigInt
quick_mul_hi(const BigInt
&other
) const {
638 multiword::quick_mul_hi(result
.val
, val
, other
.val
);
642 // BigInt(x).pow_n(n) computes x ^ n.
644 LIBC_INLINE
constexpr void pow_n(uint64_t power
) {
645 static_assert(!Signed
);
646 BigInt result
= one();
647 BigInt cur_power
= *this;
652 cur_power
*= cur_power
;
657 // Performs inplace signed / unsigned division. Returns remainder if not
659 // For signed numbers it behaves like C++ signed integer division.
660 // That is by truncating the fractionnal part
661 // https://stackoverflow.com/a/3602857
662 LIBC_INLINE
constexpr cpp::optional
<BigInt
> div(const BigInt
÷r
) {
663 if (LIBC_UNLIKELY(divider
.is_zero()))
665 if (LIBC_UNLIKELY(divider
== BigInt::one()))
666 return BigInt::zero();
668 if constexpr (SIGNED
)
669 result
= divide_signed(*this, divider
);
671 result
= divide_unsigned(*this, divider
);
672 *this = result
.quotient
;
673 return result
.remainder
;
676 // Efficiently perform BigInt / (x * 2^e), where x is a half-word-size
677 // unsigned integer, and return the remainder. The main idea is as follow:
678 // Let q = y / (x * 2^e) be the quotient, and
679 // r = y % (x * 2^e) be the remainder.
680 // First, notice that:
681 // r % (2^e) = y % (2^e),
682 // so we just need to focus on all the bits of y that is >= 2^e.
683 // To speed up the shift-and-add steps, we only use x as the divisor, and
684 // performing 32-bit shiftings instead of bit-by-bit shiftings.
685 // Since the remainder of each division step < x < 2^(WORD_SIZE / 2), the
686 // computation of each step is now properly contained within WordType.
687 // And finally we perform some extra alignment steps for the remaining bits.
688 LIBC_INLINE
constexpr cpp::optional
<BigInt
>
689 div_uint_half_times_pow_2(multiword::half_width_t
<WordType
> x
, size_t e
) {
695 *this = BigInt
<Bits
, false, WordType
>();
699 WordType x_word
= static_cast<WordType
>(x
);
700 constexpr size_t LOG2_WORD_SIZE
= cpp::bit_width(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))
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)
710 // pos is the index of the current 64-bit chunk that we are processing.
711 size_t pos
= WORD_COUNT
;
713 // TODO: look into if constexpr(Bits > 256) skip leading zeroes.
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
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
722 rem
<<= HALF_WORD_SIZE
;
723 rem
+= val
[--pos
] >> HALF_WORD_SIZE
;
724 WordType q_tmp
= rem
/ x_word
;
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
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
;
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
;
747 if (last_shift
> 0) {
748 // quotient * 2^(lower - e)
749 quotient
<<= last_shift
;
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
;
758 q_tmp
= rem
/ x_word
;
760 last_shift
-= HALF_WORD_SIZE
;
762 // Only use the upper HALF_WORD_SIZE-bit of the current WORD_SIZE-bit
764 d
>>= HALF_WORD_SIZE
;
767 if (last_shift
> 0) {
768 rem
<<= HALF_WORD_SIZE
;
770 q_tmp
<<= last_shift
;
771 x_word
<<= HALF_WORD_SIZE
- last_shift
;
772 q_tmp
+= rem
/ x_word
;
776 quotient
.val
[0] += q_tmp
;
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
;
784 remainder
[pos
] = (rem
<< HALF_WORD_SIZE
) + (val
[pos
] & HALF_MASK
);
786 remainder
[pos
] = rem
;
790 remainder
[pos
] = rem
;
793 // Set the remaining lower bits of the remainder.
794 for (; pos
> 0; --pos
) {
795 remainder
[pos
- 1] = val
[pos
- 1];
802 LIBC_INLINE
constexpr BigInt
operator/(const BigInt
&other
) const {
803 BigInt
result(*this);
808 LIBC_INLINE
constexpr BigInt
&operator/=(const BigInt
&other
) {
813 LIBC_INLINE
constexpr BigInt
operator%(const BigInt
&other
) const {
814 BigInt
result(*this);
815 return *result
.div(other
);
818 LIBC_INLINE
constexpr BigInt
operator%=(const BigInt
&other
) {
819 *this = *this % other
;
823 LIBC_INLINE
constexpr BigInt
&operator*=(const BigInt
&other
) {
824 *this = *this * other
;
828 LIBC_INLINE
constexpr BigInt
&operator<<=(size_t s
) {
829 val
= multiword::shift
<multiword::LEFT
, SIGNED
>(val
, s
);
833 LIBC_INLINE
constexpr BigInt
operator<<(size_t s
) const {
834 return BigInt(multiword::shift
<multiword::LEFT
, SIGNED
>(val
, s
));
837 LIBC_INLINE
constexpr BigInt
&operator>>=(size_t s
) {
838 val
= multiword::shift
<multiword::RIGHT
, SIGNED
>(val
, s
);
842 LIBC_INLINE
constexpr BigInt
operator>>(size_t s
) const {
843 return BigInt(multiword::shift
<multiword::RIGHT
, SIGNED
>(val
, s
));
846 #define DEFINE_BINOP(OP) \
847 LIBC_INLINE friend constexpr BigInt operator OP(const BigInt &lhs, \
848 const BigInt &rhs) { \
850 for (size_t i = 0; i < WORD_COUNT; ++i) \
851 result[i] = lhs[i] OP rhs[i]; \
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]; \
861 DEFINE_BINOP(&) // & and &=
862 DEFINE_BINOP(|) // | and |=
863 DEFINE_BINOP(^) // ^ and ^=
866 LIBC_INLINE
constexpr BigInt
operator~() const {
868 for (size_t i
= 0; i
< WORD_COUNT
; ++i
)
873 LIBC_INLINE
constexpr BigInt
operator-() const {
874 BigInt
result(*this);
879 LIBC_INLINE
friend constexpr bool operator==(const BigInt
&lhs
,
881 for (size_t i
= 0; i
< WORD_COUNT
; ++i
)
882 if (lhs
.val
[i
] != rhs
.val
[i
])
887 LIBC_INLINE
friend constexpr bool operator!=(const BigInt
&lhs
,
889 return !(lhs
== rhs
);
892 LIBC_INLINE
friend constexpr bool operator>(const BigInt
&lhs
,
894 return cmp(lhs
, rhs
) > 0;
896 LIBC_INLINE
friend constexpr bool operator>=(const BigInt
&lhs
,
898 return cmp(lhs
, rhs
) >= 0;
900 LIBC_INLINE
friend constexpr bool operator<(const BigInt
&lhs
,
902 return cmp(lhs
, rhs
) < 0;
904 LIBC_INLINE
friend constexpr bool operator<=(const BigInt
&lhs
,
906 return cmp(lhs
, rhs
) <= 0;
909 LIBC_INLINE
constexpr BigInt
&operator++() {
914 LIBC_INLINE
constexpr BigInt
operator++(int) {
915 BigInt
oldval(*this);
920 LIBC_INLINE
constexpr BigInt
&operator--() {
925 LIBC_INLINE
constexpr BigInt
operator--(int) {
926 BigInt
oldval(*this);
931 // Return the i-th word of the number.
932 LIBC_INLINE
constexpr const WordType
&operator[](size_t i
) const {
936 // Return the i-th word of the number.
937 LIBC_INLINE
constexpr WordType
&operator[](size_t i
) { return val
[i
]; }
940 LIBC_INLINE
friend constexpr int cmp(const BigInt
&lhs
, const BigInt
&rhs
) {
941 constexpr auto compare
= [](WordType a
, WordType b
) {
942 return a
== b
? 0 : a
> b
? 1 : -1;
944 if constexpr (Signed
) {
945 const bool lhs_is_neg
= lhs
.is_neg();
946 const bool rhs_is_neg
= rhs
.is_neg();
947 if (lhs_is_neg
!= rhs_is_neg
)
948 return rhs_is_neg
? 1 : -1;
950 for (size_t i
= WORD_COUNT
; i
-- > 0;)
951 if (auto cmp
= compare(lhs
[i
], rhs
[i
]); cmp
!= 0)
956 LIBC_INLINE
constexpr void bitwise_not() {
957 for (auto &part
: val
)
961 LIBC_INLINE
constexpr void negate() {
966 LIBC_INLINE
constexpr void increment() {
967 multiword::add_with_carry(val
, cpp::array
<WordType
, 1>{1});
970 LIBC_INLINE
constexpr void decrement() {
971 multiword::add_with_carry(val
, cpp::array
<WordType
, 1>{1});
974 LIBC_INLINE
constexpr void extend(size_t index
, bool is_neg
) {
975 const WordType value
= is_neg
? cpp::numeric_limits
<WordType
>::max()
976 : cpp::numeric_limits
<WordType
>::min();
977 for (size_t i
= index
; i
< WORD_COUNT
; ++i
)
981 LIBC_INLINE
constexpr bool get_msb() const {
982 return val
.back() >> (WORD_SIZE
- 1);
985 LIBC_INLINE
constexpr void set_msb() {
986 val
.back() |= mask_leading_ones
<WordType
, 1>();
989 LIBC_INLINE
constexpr void clear_msb() {
990 val
.back() &= mask_trailing_ones
<WordType
, WORD_SIZE
- 1>();
993 LIBC_INLINE
constexpr void set_bit(size_t i
) {
994 const size_t word_index
= i
/ WORD_SIZE
;
995 val
[word_index
] |= WordType(1) << (i
% WORD_SIZE
);
998 LIBC_INLINE
constexpr static Division
divide_unsigned(const BigInt
÷nd
,
999 const BigInt
÷r
) {
1000 BigInt remainder
= dividend
;
1002 if (remainder
>= divider
) {
1003 BigInt subtractor
= divider
;
1004 int cur_bit
= multiword::countl_zero(subtractor
.val
) -
1005 multiword::countl_zero(remainder
.val
);
1006 subtractor
<<= cur_bit
;
1007 for (; cur_bit
>= 0 && remainder
> 0; --cur_bit
, subtractor
>>= 1) {
1008 if (remainder
< subtractor
)
1010 remainder
-= subtractor
;
1011 quotient
.set_bit(cur_bit
);
1014 return Division
{quotient
, remainder
};
1017 LIBC_INLINE
constexpr static Division
divide_signed(const BigInt
÷nd
,
1018 const BigInt
÷r
) {
1019 // Special case because it is not possible to negate the min value of a
1021 if (dividend
== min() && divider
== min())
1022 return Division
{one(), zero()};
1023 // 1. Convert the dividend and divisor to unsigned representation.
1024 unsigned_type
udividend(dividend
);
1025 unsigned_type
udivider(divider
);
1026 // 2. Negate the dividend if it's negative, and similarly for the divisor.
1027 const bool dividend_is_neg
= dividend
.is_neg();
1028 const bool divider_is_neg
= divider
.is_neg();
1029 if (dividend_is_neg
)
1033 // 3. Use unsigned multiword division algorithm.
1034 const auto unsigned_result
= divide_unsigned(udividend
, udivider
);
1035 // 4. Convert the quotient and remainder to signed representation.
1037 result
.quotient
= signed_type(unsigned_result
.quotient
);
1038 result
.remainder
= signed_type(unsigned_result
.remainder
);
1039 // 5. Negate the quotient if the dividend and divisor had opposite signs.
1040 if (dividend_is_neg
!= divider_is_neg
)
1041 result
.quotient
.negate();
1042 // 6. Negate the remainder if the dividend was negative.
1043 if (dividend_is_neg
)
1044 result
.remainder
.negate();
1049 friend unsigned_type
;
1052 namespace internal
{
1053 // We default BigInt's WordType to 'uint64_t' or 'uint32_t' depending on type
1055 template <size_t Bits
>
1056 struct WordTypeSelector
: cpp::type_identity
<
1057 #ifdef LIBC_TYPES_HAS_INT64
1061 #endif // LIBC_TYPES_HAS_INT64
1064 // Except if we request 16 or 32 bits explicitly.
1065 template <> struct WordTypeSelector
<16> : cpp::type_identity
<uint16_t> {};
1066 template <> struct WordTypeSelector
<32> : cpp::type_identity
<uint32_t> {};
1067 template <> struct WordTypeSelector
<96> : cpp::type_identity
<uint32_t> {};
1069 template <size_t Bits
>
1070 using WordTypeSelectorT
= typename WordTypeSelector
<Bits
>::type
;
1071 } // namespace internal
1073 template <size_t Bits
>
1074 using UInt
= BigInt
<Bits
, false, internal::WordTypeSelectorT
<Bits
>>;
1076 template <size_t Bits
>
1077 using Int
= BigInt
<Bits
, true, internal::WordTypeSelectorT
<Bits
>>;
1079 // Provides limits of BigInt.
1080 template <size_t Bits
, bool Signed
, typename T
>
1081 struct cpp::numeric_limits
<BigInt
<Bits
, Signed
, T
>> {
1082 LIBC_INLINE
static constexpr BigInt
<Bits
, Signed
, T
> max() {
1083 return BigInt
<Bits
, Signed
, T
>::max();
1085 LIBC_INLINE
static constexpr BigInt
<Bits
, Signed
, T
> min() {
1086 return BigInt
<Bits
, Signed
, T
>::min();
1088 // Meant to match std::numeric_limits interface.
1089 // NOLINTNEXTLINE(readability-identifier-naming)
1090 LIBC_INLINE_VAR
static constexpr int digits
= Bits
- Signed
;
1093 // type traits to determine whether a T is a BigInt.
1094 template <typename T
> struct is_big_int
: cpp::false_type
{};
1096 template <size_t Bits
, bool Signed
, typename T
>
1097 struct is_big_int
<BigInt
<Bits
, Signed
, T
>> : cpp::true_type
{};
1100 LIBC_INLINE_VAR
constexpr bool is_big_int_v
= is_big_int
<T
>::value
;
1102 // extensions of type traits to include BigInt
1104 // is_integral_or_big_int
1105 template <typename T
>
1106 struct is_integral_or_big_int
1107 : cpp::bool_constant
<(cpp::is_integral_v
<T
> || is_big_int_v
<T
>)> {};
1109 template <typename T
>
1110 LIBC_INLINE_VAR
constexpr bool is_integral_or_big_int_v
=
1111 is_integral_or_big_int
<T
>::value
;
1113 // make_big_int_unsigned
1114 template <typename T
> struct make_big_int_unsigned
;
1116 template <size_t Bits
, bool Signed
, typename T
>
1117 struct make_big_int_unsigned
<BigInt
<Bits
, Signed
, T
>>
1118 : cpp::type_identity
<BigInt
<Bits
, false, T
>> {};
1120 template <typename T
>
1121 using make_big_int_unsigned_t
= typename make_big_int_unsigned
<T
>::type
;
1123 // make_big_int_signed
1124 template <typename T
> struct make_big_int_signed
;
1126 template <size_t Bits
, bool Signed
, typename T
>
1127 struct make_big_int_signed
<BigInt
<Bits
, Signed
, T
>>
1128 : cpp::type_identity
<BigInt
<Bits
, true, T
>> {};
1130 template <typename T
>
1131 using make_big_int_signed_t
= typename make_big_int_signed
<T
>::type
;
1133 // make_integral_or_big_int_unsigned
1134 template <typename T
, class = void> struct make_integral_or_big_int_unsigned
;
1136 template <typename T
>
1137 struct make_integral_or_big_int_unsigned
<
1138 T
, cpp::enable_if_t
<cpp::is_integral_v
<T
>>> : cpp::make_unsigned
<T
> {};
1140 template <typename T
>
1141 struct make_integral_or_big_int_unsigned
<T
, cpp::enable_if_t
<is_big_int_v
<T
>>>
1142 : make_big_int_unsigned
<T
> {};
1144 template <typename T
>
1145 using make_integral_or_big_int_unsigned_t
=
1146 typename make_integral_or_big_int_unsigned
<T
>::type
;
1148 // make_integral_or_big_int_signed
1149 template <typename T
, class = void> struct make_integral_or_big_int_signed
;
1151 template <typename T
>
1152 struct make_integral_or_big_int_signed
<T
,
1153 cpp::enable_if_t
<cpp::is_integral_v
<T
>>>
1154 : cpp::make_signed
<T
> {};
1156 template <typename T
>
1157 struct make_integral_or_big_int_signed
<T
, cpp::enable_if_t
<is_big_int_v
<T
>>>
1158 : make_big_int_signed
<T
> {};
1160 template <typename T
>
1161 using make_integral_or_big_int_signed_t
=
1162 typename make_integral_or_big_int_signed
<T
>::type
;
1164 // is_unsigned_integral_or_big_int
1165 template <typename T
>
1166 struct is_unsigned_integral_or_big_int
1167 : cpp::bool_constant
<
1168 cpp::is_same_v
<T
, make_integral_or_big_int_unsigned_t
<T
>>> {};
1170 template <typename T
>
1171 // Meant to look like <type_traits> helper variable templates.
1172 // NOLINTNEXTLINE(readability-identifier-naming)
1173 LIBC_INLINE_VAR
constexpr bool is_unsigned_integral_or_big_int_v
=
1174 is_unsigned_integral_or_big_int
<T
>::value
;
1178 // Specialization of cpp::bit_cast ('bit.h') from T to BigInt.
1179 template <typename To
, typename From
>
1180 LIBC_INLINE
constexpr cpp::enable_if_t
<
1181 (sizeof(To
) == sizeof(From
)) && cpp::is_trivially_copyable
<To
>::value
&&
1182 cpp::is_trivially_copyable
<From
>::value
&& is_big_int
<To
>::value
,
1184 bit_cast(const From
&from
) {
1186 using Storage
= decltype(out
.val
);
1187 out
.val
= cpp::bit_cast
<Storage
>(from
);
1191 // Specialization of cpp::bit_cast ('bit.h') from BigInt to T.
1192 template <typename To
, size_t Bits
>
1193 LIBC_INLINE
constexpr cpp::enable_if_t
<
1194 sizeof(To
) == sizeof(UInt
<Bits
>) &&
1195 cpp::is_trivially_constructible
<To
>::value
&&
1196 cpp::is_trivially_copyable
<To
>::value
&&
1197 cpp::is_trivially_copyable
<UInt
<Bits
>>::value
,
1199 bit_cast(const UInt
<Bits
> &from
) {
1200 return cpp::bit_cast
<To
>(from
.val
);
1203 // Specialization of cpp::popcount ('bit.h') for BigInt.
1204 template <typename T
>
1205 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, int>
1208 for (auto word
: value
.val
)
1210 bits
+= popcount(word
);
1214 // Specialization of cpp::has_single_bit ('bit.h') for BigInt.
1215 template <typename T
>
1216 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, bool>
1217 has_single_bit(T value
) {
1219 for (auto word
: value
.val
) {
1222 bits
+= popcount(word
);
1229 // Specialization of cpp::countr_zero ('bit.h') for BigInt.
1230 template <typename T
>
1231 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, int>
1232 countr_zero(const T
&value
) {
1233 return multiword::countr_zero(value
.val
);
1236 // Specialization of cpp::countl_zero ('bit.h') for BigInt.
1237 template <typename T
>
1238 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, int>
1239 countl_zero(const T
&value
) {
1240 return multiword::countl_zero(value
.val
);
1243 // Specialization of cpp::countl_one ('bit.h') for BigInt.
1244 template <typename T
>
1245 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, int>
1246 countl_one(T value
) {
1247 return multiword::countl_one(value
.val
);
1250 // Specialization of cpp::countr_one ('bit.h') for BigInt.
1251 template <typename T
>
1252 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, int>
1253 countr_one(T value
) {
1254 return multiword::countr_one(value
.val
);
1257 // Specialization of cpp::bit_width ('bit.h') for BigInt.
1258 template <typename T
>
1259 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, int>
1260 bit_width(T value
) {
1261 return cpp::numeric_limits
<T
>::digits
- cpp::countl_zero(value
);
1264 // Forward-declare rotr so that rotl can use it.
1265 template <typename T
>
1266 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, T
>
1267 rotr(T value
, int rotate
);
1269 // Specialization of cpp::rotl ('bit.h') for BigInt.
1270 template <typename T
>
1271 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, T
>
1272 rotl(T value
, int rotate
) {
1273 constexpr unsigned N
= cpp::numeric_limits
<T
>::digits
;
1274 rotate
= rotate
% N
;
1278 return cpp::rotr
<T
>(value
, -rotate
);
1279 return (value
<< rotate
) | (value
>> (N
- rotate
));
1282 // Specialization of cpp::rotr ('bit.h') for BigInt.
1283 template <typename T
>
1284 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, T
>
1285 rotr(T value
, int rotate
) {
1286 constexpr unsigned N
= cpp::numeric_limits
<T
>::digits
;
1287 rotate
= rotate
% N
;
1291 return cpp::rotl
<T
>(value
, -rotate
);
1292 return (value
>> rotate
) | (value
<< (N
- rotate
));
1297 // Specialization of mask_trailing_ones ('math_extras.h') for BigInt.
1298 template <typename T
, size_t count
>
1299 LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, T
>
1300 mask_trailing_ones() {
1301 static_assert(!T::SIGNED
&& count
<= T::BITS
);
1302 if (count
== T::BITS
)
1303 return T::all_ones();
1304 constexpr size_t QUOTIENT
= count
/ T::WORD_SIZE
;
1305 constexpr size_t REMAINDER
= count
% T::WORD_SIZE
;
1306 T out
; // zero initialized
1307 for (size_t i
= 0; i
<= QUOTIENT
; ++i
)
1308 out
[i
] = i
< QUOTIENT
1310 : mask_trailing_ones
<typename
T::word_type
, REMAINDER
>();
1314 // Specialization of mask_leading_ones ('math_extras.h') for BigInt.
1315 template <typename T
, size_t count
>
1316 LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, T
> mask_leading_ones() {
1317 static_assert(!T::SIGNED
&& count
<= T::BITS
);
1318 if (count
== T::BITS
)
1319 return T::all_ones();
1320 constexpr size_t QUOTIENT
= (T::BITS
- count
- 1U) / T::WORD_SIZE
;
1321 constexpr size_t REMAINDER
= count
% T::WORD_SIZE
;
1322 T out
; // zero initialized
1323 for (size_t i
= QUOTIENT
; i
< T::WORD_COUNT
; ++i
)
1324 out
[i
] = i
> QUOTIENT
1326 : mask_leading_ones
<typename
T::word_type
, REMAINDER
>();
1330 // Specialization of mask_trailing_zeros ('math_extras.h') for BigInt.
1331 template <typename T
, size_t count
>
1332 LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, T
>
1333 mask_trailing_zeros() {
1334 return mask_leading_ones
<T
, T::BITS
- count
>();
1337 // Specialization of mask_leading_zeros ('math_extras.h') for BigInt.
1338 template <typename T
, size_t count
>
1339 LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, T
>
1340 mask_leading_zeros() {
1341 return mask_trailing_ones
<T
, T::BITS
- count
>();
1344 // Specialization of count_zeros ('math_extras.h') for BigInt.
1345 template <typename T
>
1346 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, int>
1347 count_zeros(T value
) {
1348 return cpp::popcount(~value
);
1351 // Specialization of first_leading_zero ('math_extras.h') for BigInt.
1352 template <typename T
>
1353 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, int>
1354 first_leading_zero(T value
) {
1355 return value
== cpp::numeric_limits
<T
>::max() ? 0
1356 : cpp::countl_one(value
) + 1;
1359 // Specialization of first_leading_one ('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_one(T value
) {
1363 return first_leading_zero(~value
);
1366 // Specialization of first_trailing_zero ('math_extras.h') for BigInt.
1367 template <typename T
>
1368 [[nodiscard
]] LIBC_INLINE
constexpr cpp::enable_if_t
<is_big_int_v
<T
>, int>
1369 first_trailing_zero(T value
) {
1370 return value
== cpp::numeric_limits
<T
>::max() ? 0
1371 : cpp::countr_zero(~value
) + 1;
1374 // Specialization of first_trailing_one ('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_one(T value
) {
1378 return value
== cpp::numeric_limits
<T
>::max() ? 0
1379 : cpp::countr_zero(value
) + 1;
1382 } // namespace LIBC_NAMESPACE_DECL
1384 #endif // LLVM_LIBC_SRC___SUPPORT_BIG_INT_H