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>(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)); 85 } 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)); 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>(__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(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 ? -1 : 0; 288 return array[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[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((i / WORD_SIZE_RATIO) + 1, 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(i, 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(i * WORD_SIZE_RATIO, 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 !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) { 474 if (v == 0) { 475 extend(i, is_neg); 476 return; 477 } 478 val[i] = static_cast<WordType>(v); 479 if constexpr (T_SIZE > WORD_SIZE) 480 v >>= WORD_SIZE; 481 else 482 v = 0; 483 } 484 } 485 LIBC_INLINE constexpr BigInt &operator=(const BigInt &other) = default; 486 487 // constants 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() { 492 BigInt out; 493 if constexpr (SIGNED) 494 out.set_msb(); 495 return out; 496 } 497 LIBC_INLINE static constexpr BigInt max() { 498 BigInt out = all_ones(); 499 if constexpr (SIGNED) 500 out.clear_msb(); 501 return out; 502 } 503 504 // TODO: Reuse the Sign type. 505 LIBC_INLINE constexpr bool is_neg() const { return SIGNED && get_msb(); } 506 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); 511 } 512 513 template <typename T> LIBC_INLINE constexpr explicit operator T() const { 514 return to<T>(); 515 } 516 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> 520 to() const { 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) 524 return lo; 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); 532 if (is_neg()) 533 lo |= MASK; 534 } 535 return lo; 536 } 537 538 LIBC_INLINE constexpr explicit operator bool() const { return !is_zero(); } 539 540 LIBC_INLINE constexpr bool is_zero() const { 541 for (auto part : val) 542 if (part != 0) 543 return false; 544 return true; 545 } 546 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); 551 } 552 553 LIBC_INLINE constexpr BigInt operator+(const BigInt &other) const { 554 BigInt result = *this; 555 result.add_overflow(other); 556 return result; 557 } 558 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. 564 return other; 565 } 566 567 LIBC_INLINE constexpr BigInt &operator+=(const BigInt &other) { 568 add_overflow(other); // Returned carry value is ignored. 569 return *this; 570 } 571 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); 576 } 577 578 LIBC_INLINE constexpr BigInt operator-(const BigInt &other) const { 579 BigInt result = *this; 580 result.sub_overflow(other); // Returned carry value is ignored. 581 return result; 582 } 583 584 LIBC_INLINE constexpr BigInt operator-(BigInt &&other) const { 585 BigInt result = *this; 586 result.sub_overflow(other); // Returned carry value is ignored. 587 return result; 588 } 589 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. 593 return *this; 594 } 595 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); 599 } 600 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); 607 return result; 608 } 609 610 LIBC_INLINE constexpr BigInt operator*(const BigInt &other) const { 611 // Perform full mul and truncate. 612 return BigInt(ful_mul(other)); 613 } 614 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 618 // bounded by: 619 // 0 <= (a.full_mul(b) >> Bits) - a.quick_mul_hi(b)) <= WORD_COUNT - 1. 620 // 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. 628 // 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 632 // 128 2 4 3 1 633 // 196 3 9 6 2 634 // 256 4 16 10 3 635 // 512 8 64 36 7 636 LIBC_INLINE constexpr BigInt quick_mul_hi(const BigInt &other) const { 637 BigInt result; 638 multiword::quick_mul_hi(result.val, val, other.val); 639 return result; 640 } 641 642 // BigInt(x).pow_n(n) computes x ^ n. 643 // Note 0 ^ 0 == 1. 644 LIBC_INLINE constexpr void pow_n(uint64_t power) { 645 static_assert(!Signed); 646 BigInt result = one(); 647 BigInt cur_power = *this; 648 while (power > 0) { 649 if ((power % 2) > 0) 650 result *= cur_power; 651 power >>= 1; 652 cur_power *= cur_power; 653 } 654 *this = result; 655 } 656 657 // Performs inplace signed / unsigned division. Returns remainder if not 658 // dividing by zero. 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())) 664 return cpp::nullopt; 665 if (LIBC_UNLIKELY(divider == BigInt::one())) 666 return BigInt::zero(); 667 Division result; 668 if constexpr (SIGNED) 669 result = divide_signed(*this, divider); 670 else 671 result = divide_unsigned(*this, divider); 672 *this = result.quotient; 673 return result.remainder; 674 } 675 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) { 690 BigInt remainder; 691 if (x == 0) 692 return cpp::nullopt; 693 if (e >= Bits) { 694 remainder = *this; 695 *this = BigInt<Bits, false, WordType>(); 696 return remainder; 697 } 698 BigInt quotient; 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)) 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(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] = ~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 private: 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; 943 }; 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; 949 } 950 for (size_t i = WORD_COUNT; i-- > 0;) 951 if (auto cmp = compare(lhs[i], rhs[i]); cmp != 0) 952 return cmp; 953 return 0; 954 } 955 956 LIBC_INLINE constexpr void bitwise_not() { 957 for (auto &part : val) 958 part = ~part; 959 } 960 961 LIBC_INLINE constexpr void negate() { 962 bitwise_not(); 963 increment(); 964 } 965 966 LIBC_INLINE constexpr void increment() { 967 multiword::add_with_carry(val, cpp::array<WordType, 1>{1}); 968 } 969 970 LIBC_INLINE constexpr void decrement() { 971 multiword::add_with_carry(val, cpp::array<WordType, 1>{1}); 972 } 973 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) 978 val[i] = value; 979 } 980 981 LIBC_INLINE constexpr bool get_msb() const { 982 return val.back() >> (WORD_SIZE - 1); 983 } 984 985 LIBC_INLINE constexpr void set_msb() { 986 val.back() |= mask_leading_ones<WordType, 1>(); 987 } 988 989 LIBC_INLINE constexpr void clear_msb() { 990 val.back() &= mask_trailing_ones<WordType, WORD_SIZE - 1>(); 991 } 992 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); 996 } 997 998 LIBC_INLINE constexpr static Division divide_unsigned(const BigInt ÷nd, 999 const BigInt ÷r) { 1000 BigInt remainder = dividend; 1001 BigInt quotient; 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) 1009 continue; 1010 remainder -= subtractor; 1011 quotient.set_bit(cur_bit); 1012 } 1013 } 1014 return Division{quotient, remainder}; 1015 } 1016 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 1020 // signed integer. 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) 1030 udividend.negate(); 1031 if (divider_is_neg) 1032 udivider.negate(); 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. 1036 Division result; 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(); 1045 return result; 1046 } 1047 1048 friend signed_type; 1049 friend unsigned_type; 1050 }; 1051 1052 namespace internal { 1053 // We default BigInt's WordType to 'uint64_t' or 'uint32_t' depending on type 1054 // availability. 1055 template <size_t Bits> 1056 struct WordTypeSelector : cpp::type_identity< 1057 #ifdef LIBC_TYPES_HAS_INT64 1058 uint64_t 1059 #else 1060 uint32_t 1061 #endif // LIBC_TYPES_HAS_INT64 1062 > { 1063 }; 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> {}; 1068 1069 template <size_t Bits> 1070 using WordTypeSelectorT = typename WordTypeSelector<Bits>::type; 1071 } // namespace internal 1072 1073 template <size_t Bits> 1074 using UInt = BigInt<Bits, false, internal::WordTypeSelectorT<Bits>>; 1075 1076 template <size_t Bits> 1077 using Int = BigInt<Bits, true, internal::WordTypeSelectorT<Bits>>; 1078 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(); 1084 } 1085 LIBC_INLINE static constexpr BigInt<Bits, Signed, T> min() { 1086 return BigInt<Bits, Signed, T>::min(); 1087 } 1088 // Meant to match std::numeric_limits interface. 1089 // NOLINTNEXTLINE(readability-identifier-naming) 1090 LIBC_INLINE_VAR static constexpr int digits = Bits - Signed; 1091 }; 1092 1093 // type traits to determine whether a T is a BigInt. 1094 template <typename T> struct is_big_int : cpp::false_type {}; 1095 1096 template <size_t Bits, bool Signed, typename T> 1097 struct is_big_int<BigInt<Bits, Signed, T>> : cpp::true_type {}; 1098 1099 template <class T> 1100 LIBC_INLINE_VAR constexpr bool is_big_int_v = is_big_int<T>::value; 1101 1102 // extensions of type traits to include BigInt 1103 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>)> {}; 1108 1109 template <typename T> 1110 LIBC_INLINE_VAR constexpr bool is_integral_or_big_int_v = 1111 is_integral_or_big_int<T>::value; 1112 1113 // make_big_int_unsigned 1114 template <typename T> struct make_big_int_unsigned; 1115 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>> {}; 1119 1120 template <typename T> 1121 using make_big_int_unsigned_t = typename make_big_int_unsigned<T>::type; 1122 1123 // make_big_int_signed 1124 template <typename T> struct make_big_int_signed; 1125 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>> {}; 1129 1130 template <typename T> 1131 using make_big_int_signed_t = typename make_big_int_signed<T>::type; 1132 1133 // make_integral_or_big_int_unsigned 1134 template <typename T, class = void> struct make_integral_or_big_int_unsigned; 1135 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> {}; 1139 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> {}; 1143 1144 template <typename T> 1145 using make_integral_or_big_int_unsigned_t = 1146 typename make_integral_or_big_int_unsigned<T>::type; 1147 1148 // make_integral_or_big_int_signed 1149 template <typename T, class = void> struct make_integral_or_big_int_signed; 1150 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> {}; 1155 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> {}; 1159 1160 template <typename T> 1161 using make_integral_or_big_int_signed_t = 1162 typename make_integral_or_big_int_signed<T>::type; 1163 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>>> {}; 1169 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; 1175 1176 namespace cpp { 1177 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, 1183 To> 1184 bit_cast(const From &from) { 1185 To out; 1186 using Storage = decltype(out.val); 1187 out.val = cpp::bit_cast<Storage>(from); 1188 return out; 1189 } 1190 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, 1198 To> 1199 bit_cast(const UInt<Bits> &from) { 1200 return cpp::bit_cast<To>(from.val); 1201 } 1202 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> 1206 popcount(T value) { 1207 int bits = 0; 1208 for (auto word : value.val) 1209 if (word) 1210 bits += popcount(word); 1211 return bits; 1212 } 1213 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) { 1218 int bits = 0; 1219 for (auto word : value.val) { 1220 if (word == 0) 1221 continue; 1222 bits += popcount(word); 1223 if (bits > 1) 1224 return false; 1225 } 1226 return bits == 1; 1227 } 1228 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); 1234 } 1235 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); 1241 } 1242 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); 1248 } 1249 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); 1255 } 1256 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); 1262 } 1263 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); 1268 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; 1275 if (!rotate) 1276 return value; 1277 if (rotate < 0) 1278 return cpp::rotr<T>(value, -rotate); 1279 return (value << rotate) | (value >> (N - rotate)); 1280 } 1281 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; 1288 if (!rotate) 1289 return value; 1290 if (rotate < 0) 1291 return cpp::rotl<T>(value, -rotate); 1292 return (value >> rotate) | (value << (N - rotate)); 1293 } 1294 1295 } // namespace cpp 1296 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 1309 ? -1 1310 : mask_trailing_ones<typename T::word_type, REMAINDER>(); 1311 return out; 1312 } 1313 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 1325 ? -1 1326 : mask_leading_ones<typename T::word_type, REMAINDER>(); 1327 return out; 1328 } 1329 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>(); 1335 } 1336 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>(); 1342 } 1343 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); 1349 } 1350 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; 1357 } 1358 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); 1364 } 1365 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; 1372 } 1373 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; 1380 } 1381 1382 } // namespace LIBC_NAMESPACE_DECL 1383 1384 #endif // LLVM_LIBC_SRC___SUPPORT_BIG_INT_H 1385