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_UINT_H
10 #define LLVM_LIBC_SRC_SUPPORT_UINT_H
12 #include "src/__support/CPP/array.h"
13 #include "src/__support/CPP/limits.h"
14 #include "src/__support/CPP/optional.h"
15 #include "src/__support/CPP/type_traits.h"
16 #include "src/__support/builtin_wrappers.h"
17 #include "src/__support/integer_utils.h"
18 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
19 #include "src/__support/number_pair.h"
21 #include <stddef.h> // For size_t
24 namespace __llvm_libc::cpp
{
26 template <size_t Bits
, bool Signed
> struct BigInt
{
28 static_assert(Bits
> 0 && Bits
% 64 == 0,
29 "Number of bits in BigInt should be a multiple of 64.");
30 static LIBC_INLINE_VAR
constexpr size_t WORDCOUNT
= Bits
/ 64;
31 uint64_t val
[WORDCOUNT
]{};
33 static LIBC_INLINE_VAR
constexpr uint64_t MASK32
= 0xFFFFFFFFu
;
35 static LIBC_INLINE
constexpr uint64_t low(uint64_t v
) { return v
& MASK32
; }
36 static LIBC_INLINE
constexpr uint64_t high(uint64_t v
) { return (v
>> 32) & MASK32
; }
38 LIBC_INLINE
constexpr BigInt() = default;
40 LIBC_INLINE
constexpr BigInt(const BigInt
<Bits
, Signed
> &other
) = default;
42 template <size_t OtherBits
, bool OtherSigned
>
43 LIBC_INLINE
constexpr BigInt(const BigInt
<OtherBits
, OtherSigned
> &other
) {
44 if (OtherBits
>= Bits
) {
45 for (size_t i
= 0; i
< WORDCOUNT
; ++i
)
49 for (; i
< OtherBits
/ 64; ++i
)
52 if constexpr (Signed
&& OtherSigned
) {
53 sign
= static_cast<uint64_t>(
54 -static_cast<int64_t>(other
[OtherBits
/ 64 - 1] >> 63));
56 for (; i
< WORDCOUNT
; ++i
)
61 // Construct a BigInt from a C array.
62 template <size_t N
, enable_if_t
<N
<= WORDCOUNT
, int> = 0>
63 LIBC_INLINE
constexpr BigInt(const uint64_t (&nums
)[N
]) {
64 size_t min_wordcount
= N
< WORDCOUNT
? N
: WORDCOUNT
;
66 for (; i
< min_wordcount
; ++i
)
69 // If nums doesn't completely fill val, then fill the rest with zeroes.
70 for (; i
< WORDCOUNT
; ++i
)
74 // Initialize the first word to |v| and the rest to 0.
76 typename
= cpp::enable_if_t
<is_integral_v
<T
> && sizeof(T
) <= 16>>
77 LIBC_INLINE
constexpr BigInt(T v
) {
78 val
[0] = static_cast<uint64_t>(v
);
80 if constexpr (Bits
== 64)
83 // Bits is at least 128.
85 if constexpr (sizeof(T
) == 16) {
86 val
[1] = static_cast<uint64_t>(v
>> 64);
90 uint64_t sign
= (Signed
&& (v
< 0)) ? 0xffff'ffff'ffff'ffff : 0;
91 for (; i
< WORDCOUNT
; ++i
) {
96 LIBC_INLINE
constexpr explicit BigInt(const cpp::array
<uint64_t, WORDCOUNT
> &words
) {
97 for (size_t i
= 0; i
< WORDCOUNT
; ++i
)
101 template <typename T
, typename
= cpp::enable_if_t
<cpp::is_integral_v
<T
> &&
103 !cpp::is_same_v
<T
, bool>>>
104 LIBC_INLINE
constexpr explicit operator T() const {
105 if constexpr (sizeof(T
) <= 8)
106 return static_cast<T
>(val
[0]);
109 T lo
= static_cast<T
>(val
[0]);
111 if constexpr (Bits
== 64) {
112 if constexpr (Signed
) {
113 // Extend sign for negative numbers.
114 return (val
[0] >> 63) ? ((T(-1) << 64) + lo
) : lo
;
119 return (static_cast<T
>(val
[1]) << 64) + lo
;
123 LIBC_INLINE
constexpr explicit operator bool() const { return !is_zero(); }
125 BigInt
<Bits
, Signed
> &operator=(const BigInt
<Bits
, Signed
> &other
) = default;
127 LIBC_INLINE
constexpr bool is_zero() const {
128 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
135 // Add x to this number and store the result in this number.
136 // Returns the carry value produced by the addition operation.
137 LIBC_INLINE
constexpr uint64_t add(const BigInt
<Bits
, Signed
> &x
) {
138 SumCarry
<uint64_t> s
{0, 0};
139 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
140 s
= add_with_carry_const(val
[i
], x
.val
[i
], s
.carry
);
146 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> operator+(const BigInt
<Bits
, Signed
> &other
) const {
147 BigInt
<Bits
, Signed
> result
;
148 SumCarry
<uint64_t> s
{0, 0};
149 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
150 s
= add_with_carry(val
[i
], other
.val
[i
], s
.carry
);
151 result
.val
[i
] = s
.sum
;
156 // This will only apply when initializing a variable from constant values, so
157 // it will always use the constexpr version of add_with_carry.
158 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> operator+(BigInt
<Bits
, Signed
> &&other
) const {
159 BigInt
<Bits
, Signed
> result
;
160 SumCarry
<uint64_t> s
{0, 0};
161 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
162 s
= add_with_carry_const(val
[i
], other
.val
[i
], s
.carry
);
163 result
.val
[i
] = s
.sum
;
168 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> &
169 operator+=(const BigInt
<Bits
, Signed
> &other
) {
170 add(other
); // Returned carry value is ignored.
174 // Subtract x to this number and store the result in this number.
175 // Returns the carry value produced by the subtraction operation.
176 LIBC_INLINE
constexpr uint64_t sub(const BigInt
<Bits
, Signed
> &x
) {
177 DiffBorrow
<uint64_t> d
{0, 0};
178 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
179 d
= sub_with_borrow_const(val
[i
], x
.val
[i
], d
.borrow
);
185 LIBC_INLINE BigInt
<Bits
, Signed
> operator-(const BigInt
<Bits
, Signed
> &other
) const {
186 BigInt
<Bits
, Signed
> result
;
187 DiffBorrow
<uint64_t> d
{0, 0};
188 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
189 d
= sub_with_borrow(val
[i
], other
.val
[i
], d
.borrow
);
190 result
.val
[i
] = d
.diff
;
195 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> operator-(BigInt
<Bits
, Signed
> &&other
) const {
196 BigInt
<Bits
, Signed
> result
;
197 DiffBorrow
<uint64_t> d
{0, 0};
198 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
199 d
= sub_with_borrow_const(val
[i
], other
.val
[i
], d
.borrow
);
200 result
.val
[i
] = d
.diff
;
205 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> &
206 operator-=(const BigInt
<Bits
, Signed
> &other
) {
207 // TODO(lntue): Set overflow flag / errno when carry is true.
212 // Multiply this number with x and store the result in this number. It is
213 // implemented using the long multiplication algorithm by splitting the
214 // 64-bit words of this number and |x| in to 32-bit halves but peforming
215 // the operations using 64-bit numbers. This ensures that we don't lose the
217 // Returns the carry value produced by the multiplication operation.
218 LIBC_INLINE
constexpr uint64_t mul(uint64_t x
) {
219 BigInt
<128, Signed
> partial_sum(0);
221 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
222 NumberPair
<uint64_t> prod
= full_mul(val
[i
], x
);
223 BigInt
<128, Signed
> tmp({prod
.lo
, prod
.hi
});
224 carry
+= partial_sum
.add(tmp
);
225 val
[i
] = partial_sum
.val
[0];
226 partial_sum
.val
[0] = partial_sum
.val
[1];
227 partial_sum
.val
[1] = carry
;
230 return partial_sum
.val
[1];
233 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
>
234 operator*(const BigInt
<Bits
, Signed
> &other
) const {
235 if constexpr (Signed
) {
236 BigInt
<Bits
, false> a(*this);
237 BigInt
<Bits
, false> b(other
);
238 bool a_neg
= (a
.val
[WORDCOUNT
- 1] >> 63);
239 bool b_neg
= (b
.val
[WORDCOUNT
- 1] >> 63);
244 BigInt
<Bits
, false> prod
= a
* b
;
247 return static_cast<BigInt
<Bits
, true>>(prod
);
250 if constexpr (WORDCOUNT
== 1) {
251 return {val
[0] * other
.val
[0]};
253 BigInt
<Bits
, Signed
> result(0);
254 BigInt
<128, Signed
> partial_sum(0);
256 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
257 for (size_t j
= 0; j
<= i
; j
++) {
258 NumberPair
<uint64_t> prod
= full_mul(val
[j
], other
.val
[i
- j
]);
259 BigInt
<128, Signed
> tmp({prod
.lo
, prod
.hi
});
260 carry
+= partial_sum
.add(tmp
);
262 result
.val
[i
] = partial_sum
.val
[0];
263 partial_sum
.val
[0] = partial_sum
.val
[1];
264 partial_sum
.val
[1] = carry
;
272 // Return the full product, only unsigned for now.
273 template <size_t OtherBits
>
274 LIBC_INLINE
constexpr BigInt
<Bits
+ OtherBits
, Signed
>
275 ful_mul(const BigInt
<OtherBits
, Signed
> &other
) const {
276 BigInt
<Bits
+ OtherBits
, Signed
> result(0);
277 BigInt
<128, Signed
> partial_sum(0);
279 constexpr size_t OTHER_WORDCOUNT
= BigInt
<OtherBits
, Signed
>::WORDCOUNT
;
280 for (size_t i
= 0; i
<= WORDCOUNT
+ OTHER_WORDCOUNT
- 2; ++i
) {
281 const size_t lower_idx
=
282 i
< OTHER_WORDCOUNT
? 0 : i
- OTHER_WORDCOUNT
+ 1;
283 const size_t upper_idx
= i
< WORDCOUNT
? i
: WORDCOUNT
- 1;
284 for (size_t j
= lower_idx
; j
<= upper_idx
; ++j
) {
285 NumberPair
<uint64_t> prod
= full_mul(val
[j
], other
.val
[i
- j
]);
286 BigInt
<128, Signed
> tmp({prod
.lo
, prod
.hi
});
287 carry
+= partial_sum
.add(tmp
);
289 result
.val
[i
] = partial_sum
.val
[0];
290 partial_sum
.val
[0] = partial_sum
.val
[1];
291 partial_sum
.val
[1] = carry
;
294 result
.val
[WORDCOUNT
+ OTHER_WORDCOUNT
- 1] = partial_sum
.val
[0];
298 // Fast hi part of the full product. The normal product `operator*` returns
299 // `Bits` least significant bits of the full product, while this function will
300 // approximate `Bits` most significant bits of the full product with errors
302 // 0 <= (a.full_mul(b) >> Bits) - a.quick_mul_hi(b)) <= WORDCOUNT - 1.
304 // An example usage of this is to quickly (but less accurately) compute the
305 // product of (normalized) mantissas of floating point numbers:
306 // (mant_1, mant_2) -> quick_mul_hi -> normalize leading bit
307 // is much more efficient than:
308 // (mant_1, mant_2) -> ful_mul -> normalize leading bit
309 // -> convert back to same Bits width by shifting/rounding,
310 // especially for higher precisions.
312 // Performance summary:
313 // Number of 64-bit x 64-bit -> 128-bit multiplications performed.
314 // Bits WORDCOUNT ful_mul quick_mul_hi Error bound
319 constexpr BigInt
<Bits
, Signed
>
320 LIBC_INLINE
quick_mul_hi(const BigInt
<Bits
, Signed
> &other
) const {
321 BigInt
<Bits
, Signed
> result(0);
322 BigInt
<128, Signed
> partial_sum(0);
324 // First round of accumulation for those at WORDCOUNT - 1 in the full
326 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
327 NumberPair
<uint64_t> prod
=
328 full_mul(val
[i
], other
.val
[WORDCOUNT
- 1 - i
]);
329 BigInt
<128, Signed
> tmp({prod
.lo
, prod
.hi
});
330 carry
+= partial_sum
.add(tmp
);
332 for (size_t i
= WORDCOUNT
; i
< 2 * WORDCOUNT
- 1; ++i
) {
333 partial_sum
.val
[0] = partial_sum
.val
[1];
334 partial_sum
.val
[1] = carry
;
336 for (size_t j
= i
- WORDCOUNT
+ 1; j
< WORDCOUNT
; ++j
) {
337 NumberPair
<uint64_t> prod
= full_mul(val
[j
], other
.val
[i
- j
]);
338 BigInt
<128, Signed
> tmp({prod
.lo
, prod
.hi
});
339 carry
+= partial_sum
.add(tmp
);
341 result
.val
[i
- WORDCOUNT
] = partial_sum
.val
[0];
343 result
.val
[WORDCOUNT
- 1] = partial_sum
.val
[1];
347 // pow takes a power and sets this to its starting value to that power. Zero
348 // to the zeroth power returns 1.
349 LIBC_INLINE
constexpr void pow_n(uint64_t power
) {
350 BigInt
<Bits
, Signed
> result
= 1;
351 BigInt
<Bits
, Signed
> cur_power
= *this;
354 if ((power
% 2) > 0) {
355 result
= result
* cur_power
;
358 cur_power
*= cur_power
;
363 // TODO: Make division work correctly for signed integers.
365 // div takes another BigInt of the same size and divides this by it. The value
366 // of this will be set to the quotient, and the return value is the remainder.
367 LIBC_INLINE
constexpr optional
<BigInt
<Bits
, Signed
>>
368 div(const BigInt
<Bits
, Signed
> &other
) {
369 BigInt
<Bits
, Signed
> remainder(0);
372 *this = BigInt
<Bits
, Signed
>(0);
382 BigInt
<Bits
, Signed
> quotient(0);
383 BigInt
<Bits
, Signed
> subtractor
= other
;
384 int cur_bit
= subtractor
.clz() - this->clz();
385 subtractor
.shift_left(cur_bit
);
387 for (; cur_bit
>= 0 && *this > 0; --cur_bit
, subtractor
.shift_right(1)) {
388 if (*this >= subtractor
) {
389 this->sub(subtractor
);
390 quotient
= quotient
| (BigInt
<Bits
, Signed
>(1) << cur_bit
);
398 // Efficiently perform BigInt / (x * 2^e), where x is a 32-bit unsigned
399 // integer, and return the remainder. The main idea is as follow:
400 // Let q = y / (x * 2^e) be the quotient, and
401 // r = y % (x * 2^e) be the remainder.
402 // First, notice that:
403 // r % (2^e) = y % (2^e),
404 // so we just need to focus on all the bits of y that is >= 2^e.
405 // To speed up the shift-and-add steps, we only use x as the divisor, and
406 // performing 32-bit shiftings instead of bit-by-bit shiftings.
407 // Since the remainder of each division step < x < 2^32, the computation of
408 // each step is now properly contained within uint64_t.
409 // And finally we perform some extra alignment steps for the remaining bits.
410 LIBC_INLINE
constexpr optional
<BigInt
<Bits
, Signed
>> div_uint32_times_pow_2(uint32_t x
,
412 BigInt
<Bits
, Signed
> remainder(0);
419 *this = BigInt
<Bits
, false>(0);
423 BigInt
<Bits
, Signed
> quotient(0);
424 uint64_t x64
= static_cast<uint64_t>(x
);
425 // lower64 = smallest multiple of 64 that is >= e.
426 size_t lower64
= ((e
>> 6) + ((e
& 63) != 0)) << 6;
427 // lower_pos is the index of the closest 64-bit chunk >= 2^e.
428 size_t lower_pos
= lower64
/ 64;
429 // Keep track of current remainder mod x * 2^(32*i)
431 // pos is the index of the current 64-bit chunk that we are processing.
432 size_t pos
= WORDCOUNT
;
434 for (size_t q_pos
= WORDCOUNT
- lower_pos
; q_pos
> 0; --q_pos
) {
435 // q_pos is 1 + the index of the current 64-bit chunk of the quotient
437 // Performing the division / modulus with divisor:
438 // x * 2^(64*q_pos - 32),
439 // i.e. using the upper 32-bit of the current 64-bit chunk.
441 rem
+= val
[--pos
] >> 32;
442 uint64_t q_tmp
= rem
/ x64
;
445 // Performing the division / modulus with divisor:
446 // x * 2^(64*(q_pos - 1)),
447 // i.e. using the lower 32-bit of the current 64-bit chunk.
449 rem
+= val
[pos
] & MASK32
;
450 quotient
.val
[q_pos
- 1] = (q_tmp
<< 32) + rem
/ x64
;
454 // So far, what we have is:
455 // quotient = y / (x * 2^lower64), and
456 // rem = (y % (x * 2^lower64)) / 2^lower64.
457 // If (lower64 > e), we will need to perform an extra adjustment of the
458 // quotient and remainder, namely:
459 // y / (x * 2^e) = [ y / (x * 2^lower64) ] * 2^(lower64 - e) +
460 // + (rem * 2^(lower64 - e)) / x
461 // (y % (x * 2^e)) / 2^e = (rem * 2^(lower64 - e)) % x
462 size_t last_shift
= lower64
- e
;
464 if (last_shift
> 0) {
465 // quotient * 2^(lower64 - e)
466 quotient
<<= last_shift
;
468 uint64_t d
= val
[--pos
];
469 if (last_shift
>= 32) {
470 // The shifting (rem * 2^(lower64 - e)) might overflow uint64_t, so we
471 // perform a 32-bit shift first.
479 // Only use the upper 32-bit of the current 64-bit chunk.
483 if (last_shift
> 0) {
486 q_tmp
<<= last_shift
;
487 x64
<<= 32 - last_shift
;
492 quotient
.val
[0] += q_tmp
;
494 if (lower64
- e
<= 32) {
495 // The remainder rem * 2^(lower64 - e) might overflow to the higher
497 if (pos
< WORDCOUNT
- 1) {
498 remainder
[pos
+ 1] = rem
>> 32;
500 remainder
[pos
] = (rem
<< 32) + (val
[pos
] & MASK32
);
502 remainder
[pos
] = rem
;
506 remainder
[pos
] = rem
;
509 // Set the remaining lower bits of the remainder.
510 for (; pos
> 0; --pos
) {
511 remainder
[pos
- 1] = val
[pos
- 1];
518 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
>
519 operator/(const BigInt
<Bits
, Signed
> &other
) const {
520 BigInt
<Bits
, Signed
> result(*this);
525 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> &
526 operator/=(const BigInt
<Bits
, Signed
> &other
) {
531 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
>
532 operator%(const BigInt
<Bits
, Signed
> &other
) const {
533 BigInt
<Bits
, Signed
> result(*this);
534 return *result
.div(other
);
537 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> &
538 operator*=(const BigInt
<Bits
, Signed
> &other
) {
539 *this = *this * other
;
543 LIBC_INLINE
constexpr uint64_t clz() {
544 uint64_t leading_zeroes
= 0;
545 for (size_t i
= WORDCOUNT
; i
> 0; --i
) {
546 if (val
[i
- 1] == 0) {
547 leading_zeroes
+= sizeof(uint64_t) * 8;
549 leading_zeroes
+= unsafe_clz(val
[i
- 1]);
553 return leading_zeroes
;
556 LIBC_INLINE
constexpr void shift_left(size_t s
) {
557 #ifdef __SIZEOF_INT128__
558 if constexpr (Bits
== 128) {
559 // Use builtin 128 bits if available;
565 __uint128_t tmp
= __uint128_t(val
[0]) + (__uint128_t(val
[1]) << 64);
567 val
[0] = uint64_t(tmp
);
568 val
[1] = uint64_t(tmp
>> 64);
571 #endif // __SIZEOF_INT128__
572 if (LIBC_UNLIKELY(s
== 0))
575 const size_t drop
= s
/ 64; // Number of words to drop
576 const size_t shift
= s
% 64; // Bits to shift in the remaining words.
577 size_t i
= WORDCOUNT
;
579 if (drop
< WORDCOUNT
) {
582 for (size_t j
= WORDCOUNT
- 1 - drop
; j
> 0; --i
, --j
) {
583 val
[i
] = (val
[j
] << shift
) | (val
[j
- 1] >> (64 - shift
));
585 val
[i
] = val
[0] << shift
;
587 for (size_t j
= WORDCOUNT
- 1 - drop
; j
> 0; --i
, --j
) {
594 for (size_t j
= 0; j
< i
; ++j
) {
599 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> operator<<(size_t s
) const {
600 BigInt
<Bits
, Signed
> result(*this);
601 result
.shift_left(s
);
605 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> &operator<<=(size_t s
) {
610 LIBC_INLINE
constexpr void shift_right(size_t s
) {
611 #ifdef __SIZEOF_INT128__
612 if constexpr (Bits
== 128) {
613 // Use builtin 128 bits if available;
619 __uint128_t tmp
= __uint128_t(val
[0]) + (__uint128_t(val
[1]) << 64);
620 if constexpr (Signed
) {
621 tmp
= static_cast<__uint128_t
>(static_cast<__int128_t
>(tmp
) >> s
);
625 val
[0] = uint64_t(tmp
);
626 val
[1] = uint64_t(tmp
>> 64);
629 #endif // __SIZEOF_INT128__
631 if (LIBC_UNLIKELY(s
== 0))
633 const size_t drop
= s
/ 64; // Number of words to drop
634 const size_t shift
= s
% 64; // Bit shift in the remaining words.
637 uint64_t sign
= Signed
? (val
[WORDCOUNT
- 1] >> 63) : 0;
639 if (drop
< WORDCOUNT
) {
641 for (size_t j
= drop
; j
< WORDCOUNT
- 1; ++i
, ++j
) {
642 val
[i
] = (val
[j
] >> shift
) | (val
[j
+ 1] << (64 - shift
));
644 if constexpr (Signed
) {
645 val
[i
] = static_cast<uint64_t>(
646 static_cast<int64_t>(val
[WORDCOUNT
- 1]) >> shift
);
648 val
[i
] = val
[WORDCOUNT
- 1] >> shift
;
652 for (size_t j
= drop
; j
< WORDCOUNT
; ++i
, ++j
) {
658 for (; i
< WORDCOUNT
; ++i
) {
663 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> operator>>(size_t s
) const {
664 BigInt
<Bits
, Signed
> result(*this);
665 result
.shift_right(s
);
669 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> &operator>>=(size_t s
) {
674 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
>
675 operator&(const BigInt
<Bits
, Signed
> &other
) const {
676 BigInt
<Bits
, Signed
> result
;
677 for (size_t i
= 0; i
< WORDCOUNT
; ++i
)
678 result
.val
[i
] = val
[i
] & other
.val
[i
];
682 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> &
683 operator&=(const BigInt
<Bits
, Signed
> &other
) {
684 for (size_t i
= 0; i
< WORDCOUNT
; ++i
)
685 val
[i
] &= other
.val
[i
];
689 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
>
690 operator|(const BigInt
<Bits
, Signed
> &other
) const {
691 BigInt
<Bits
, Signed
> result
;
692 for (size_t i
= 0; i
< WORDCOUNT
; ++i
)
693 result
.val
[i
] = val
[i
] | other
.val
[i
];
697 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> &
698 operator|=(const BigInt
<Bits
, Signed
> &other
) {
699 for (size_t i
= 0; i
< WORDCOUNT
; ++i
)
700 val
[i
] |= other
.val
[i
];
704 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
>
705 operator^(const BigInt
<Bits
, Signed
> &other
) const {
706 BigInt
<Bits
, Signed
> result
;
707 for (size_t i
= 0; i
< WORDCOUNT
; ++i
)
708 result
.val
[i
] = val
[i
] ^ other
.val
[i
];
712 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> &
713 operator^=(const BigInt
<Bits
, Signed
> &other
) {
714 for (size_t i
= 0; i
< WORDCOUNT
; ++i
)
715 val
[i
] ^= other
.val
[i
];
719 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> operator~() const {
720 BigInt
<Bits
, Signed
> result
;
721 for (size_t i
= 0; i
< WORDCOUNT
; ++i
)
722 result
.val
[i
] = ~val
[i
];
726 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> operator-() const {
727 BigInt
<Bits
, Signed
> result
= ~(*this);
728 result
.add(BigInt
<Bits
, Signed
>(1));
732 LIBC_INLINE
constexpr bool operator==(const BigInt
<Bits
, Signed
> &other
) const {
733 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
734 if (val
[i
] != other
.val
[i
])
740 LIBC_INLINE
constexpr bool operator!=(const BigInt
<Bits
, Signed
> &other
) const {
741 for (size_t i
= 0; i
< WORDCOUNT
; ++i
) {
742 if (val
[i
] != other
.val
[i
])
748 LIBC_INLINE
constexpr bool operator>(const BigInt
<Bits
, Signed
> &other
) const {
749 if constexpr (Signed
) {
750 // Check for different signs;
751 bool a_sign
= val
[WORDCOUNT
- 1] >> 63;
752 bool b_sign
= other
.val
[WORDCOUNT
- 1] >> 63;
753 if (a_sign
!= b_sign
) {
757 for (size_t i
= WORDCOUNT
; i
> 0; --i
) {
758 uint64_t word
= val
[i
- 1];
759 uint64_t other_word
= other
.val
[i
- 1];
760 if (word
> other_word
)
762 else if (word
< other_word
)
769 LIBC_INLINE
constexpr bool operator>=(const BigInt
<Bits
, Signed
> &other
) const {
770 if constexpr (Signed
) {
771 // Check for different signs;
772 bool a_sign
= val
[WORDCOUNT
- 1] >> 63;
773 bool b_sign
= other
.val
[WORDCOUNT
- 1] >> 63;
774 if (a_sign
!= b_sign
) {
778 for (size_t i
= WORDCOUNT
; i
> 0; --i
) {
779 uint64_t word
= val
[i
- 1];
780 uint64_t other_word
= other
.val
[i
- 1];
781 if (word
> other_word
)
783 else if (word
< other_word
)
790 LIBC_INLINE
constexpr bool operator<(const BigInt
<Bits
, Signed
> &other
) const {
791 if constexpr (Signed
) {
792 // Check for different signs;
793 bool a_sign
= val
[WORDCOUNT
- 1] >> 63;
794 bool b_sign
= other
.val
[WORDCOUNT
- 1] >> 63;
795 if (a_sign
!= b_sign
) {
800 for (size_t i
= WORDCOUNT
; i
> 0; --i
) {
801 uint64_t word
= val
[i
- 1];
802 uint64_t other_word
= other
.val
[i
- 1];
803 if (word
> other_word
)
805 else if (word
< other_word
)
812 LIBC_INLINE
constexpr bool operator<=(const BigInt
<Bits
, Signed
> &other
) const {
813 if constexpr (Signed
) {
814 // Check for different signs;
815 bool a_sign
= val
[WORDCOUNT
- 1] >> 63;
816 bool b_sign
= other
.val
[WORDCOUNT
- 1] >> 63;
817 if (a_sign
!= b_sign
) {
821 for (size_t i
= WORDCOUNT
; i
> 0; --i
) {
822 uint64_t word
= val
[i
- 1];
823 uint64_t other_word
= other
.val
[i
- 1];
824 if (word
> other_word
)
826 else if (word
< other_word
)
833 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> &operator++() {
834 BigInt
<Bits
, Signed
> one(1);
839 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> operator++(int) {
840 BigInt
<Bits
, Signed
> oldval(*this);
841 BigInt
<Bits
, Signed
> one(1);
846 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> &operator--() {
847 BigInt
<Bits
, Signed
> one(1);
852 LIBC_INLINE
constexpr BigInt
<Bits
, Signed
> operator--(int) {
853 BigInt
<Bits
, Signed
> oldval(*this);
854 BigInt
<Bits
, Signed
> one(1);
859 // Return the i-th 64-bit word of the number.
860 LIBC_INLINE
constexpr const uint64_t &operator[](size_t i
) const { return val
[i
]; }
862 // Return the i-th 64-bit word of the number.
863 LIBC_INLINE
constexpr uint64_t &operator[](size_t i
) { return val
[i
]; }
865 LIBC_INLINE
uint64_t *data() { return val
; }
867 LIBC_INLINE
const uint64_t *data() const { return val
; }
870 template <size_t Bits
> using UInt
= BigInt
<Bits
, false>;
872 template <size_t Bits
> using Int
= BigInt
<Bits
, true>;
874 // Provides limits of U/Int<128>.
875 template <> class numeric_limits
<UInt
<128>> {
877 LIBC_INLINE
static constexpr UInt
<128> max() {
878 return UInt
<128>({0xffff'ffff'ffff'ffff, 0xffff'ffff'ffff'ffff});
880 static constexpr UInt
<128> min() { return UInt
<128>(0); }
883 template <> class numeric_limits
<Int
<128>> {
885 LIBC_INLINE
static constexpr Int
<128> max() {
886 return Int
<128>({0xffff'ffff'ffff'ffff, 0x7fff'ffff'ffff'ffff});
888 LIBC_INLINE
static constexpr Int
<128> min() {
889 return Int
<128>({0, 0x8000'0000'0000'0000});
893 // Provides is_integral of U/Int<128>, U/Int<192>, U/Int<256>.
894 template <size_t Bits
, bool Signed
>
895 struct is_integral
<BigInt
<Bits
, Signed
>> : cpp::true_type
{
896 static_assert(Bits
> 0 && Bits
% 64 == 0,
897 "Number of bits in BigInt should be a multiple of 64.");
900 // Provides is_unsigned of UInt<128>, UInt<192>, UInt<256>.
901 template <size_t Bits
> struct is_unsigned
<UInt
<Bits
>> : public cpp::true_type
{
902 static_assert(Bits
> 0 && Bits
% 64 == 0,
903 "Number of bits in UInt should be a multiple of 64.");
906 template <size_t Bits
>
907 struct make_unsigned
<Int
<Bits
>> : type_identity
<UInt
<Bits
>> {
908 static_assert(Bits
> 0 && Bits
% 64 == 0,
909 "Number of bits in Int should be a multiple of 64.");
912 } // namespace __llvm_libc::cpp
914 #endif // LLVM_LIBC_SRC_SUPPORT_UINT_H