File indexing completed on 2025-01-18 09:27:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #ifndef ABSL_NUMERIC_INT128_H_
0027 #define ABSL_NUMERIC_INT128_H_
0028
0029 #include <cassert>
0030 #include <cmath>
0031 #include <cstdint>
0032 #include <cstring>
0033 #include <iosfwd>
0034 #include <limits>
0035 #include <string>
0036 #include <utility>
0037
0038 #include "absl/base/config.h"
0039 #include "absl/base/macros.h"
0040 #include "absl/base/port.h"
0041 #include "absl/types/compare.h"
0042
0043 #if defined(_MSC_VER)
0044
0045
0046
0047
0048 #define ABSL_INTERNAL_WCHAR_T __wchar_t
0049 #if defined(_M_X64) && !defined(_M_ARM64EC)
0050 #include <intrin.h>
0051 #pragma intrinsic(_umul128)
0052 #endif
0053 #else
0054 #define ABSL_INTERNAL_WCHAR_T wchar_t
0055 #endif
0056
0057 namespace absl {
0058 ABSL_NAMESPACE_BEGIN
0059
0060 class int128;
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 class
0107 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0108 alignas(unsigned __int128)
0109 #endif
0110 uint128 {
0111 public:
0112 uint128() = default;
0113
0114
0115 constexpr uint128(int v);
0116 constexpr uint128(unsigned int v);
0117 constexpr uint128(long v);
0118 constexpr uint128(unsigned long v);
0119 constexpr uint128(long long v);
0120 constexpr uint128(unsigned long long v);
0121 #ifdef ABSL_HAVE_INTRINSIC_INT128
0122 constexpr uint128(__int128 v);
0123 constexpr uint128(unsigned __int128 v);
0124 #endif
0125 constexpr uint128(int128 v);
0126 explicit uint128(float v);
0127 explicit uint128(double v);
0128 explicit uint128(long double v);
0129
0130
0131 uint128& operator=(int v);
0132 uint128& operator=(unsigned int v);
0133 uint128& operator=(long v);
0134 uint128& operator=(unsigned long v);
0135 uint128& operator=(long long v);
0136 uint128& operator=(unsigned long long v);
0137 #ifdef ABSL_HAVE_INTRINSIC_INT128
0138 uint128& operator=(__int128 v);
0139 uint128& operator=(unsigned __int128 v);
0140 #endif
0141 uint128& operator=(int128 v);
0142
0143
0144 constexpr explicit operator bool() const;
0145 constexpr explicit operator char() const;
0146 constexpr explicit operator signed char() const;
0147 constexpr explicit operator unsigned char() const;
0148 constexpr explicit operator char16_t() const;
0149 constexpr explicit operator char32_t() const;
0150 constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const;
0151 constexpr explicit operator short() const;
0152
0153 constexpr explicit operator unsigned short() const;
0154 constexpr explicit operator int() const;
0155 constexpr explicit operator unsigned int() const;
0156 constexpr explicit operator long() const;
0157
0158 constexpr explicit operator unsigned long() const;
0159
0160 constexpr explicit operator long long() const;
0161
0162 constexpr explicit operator unsigned long long() const;
0163 #ifdef ABSL_HAVE_INTRINSIC_INT128
0164 constexpr explicit operator __int128() const;
0165 constexpr explicit operator unsigned __int128() const;
0166 #endif
0167 explicit operator float() const;
0168 explicit operator double() const;
0169 explicit operator long double() const;
0170
0171
0172
0173
0174 uint128& operator+=(uint128 other);
0175 uint128& operator-=(uint128 other);
0176 uint128& operator*=(uint128 other);
0177
0178 uint128& operator/=(uint128 other);
0179 uint128& operator%=(uint128 other);
0180 uint128 operator++(int);
0181 uint128 operator--(int);
0182 uint128& operator<<=(int);
0183 uint128& operator>>=(int);
0184 uint128& operator&=(uint128 other);
0185 uint128& operator|=(uint128 other);
0186 uint128& operator^=(uint128 other);
0187 uint128& operator++();
0188 uint128& operator--();
0189
0190
0191
0192
0193 friend constexpr uint64_t Uint128Low64(uint128 v);
0194
0195
0196
0197
0198 friend constexpr uint64_t Uint128High64(uint128 v);
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209 friend constexpr uint128 MakeUint128(uint64_t high, uint64_t low);
0210
0211
0212
0213
0214 friend constexpr uint128 Uint128Max();
0215
0216
0217 template <typename H>
0218 friend H AbslHashValue(H h, uint128 v) {
0219 return H::combine(std::move(h), Uint128High64(v), Uint128Low64(v));
0220 }
0221
0222
0223 template <typename Sink>
0224 friend void AbslStringify(Sink& sink, uint128 v) {
0225 sink.Append(v.ToString());
0226 }
0227
0228 private:
0229 constexpr uint128(uint64_t high, uint64_t low);
0230
0231 std::string ToString() const;
0232
0233
0234
0235
0236
0237 #if defined(ABSL_IS_LITTLE_ENDIAN)
0238 uint64_t lo_;
0239 uint64_t hi_;
0240 #elif defined(ABSL_IS_BIG_ENDIAN)
0241 uint64_t hi_;
0242 uint64_t lo_;
0243 #else
0244 #error "Unsupported byte order: must be little-endian or big-endian."
0245 #endif
0246 };
0247
0248
0249 std::ostream& operator<<(std::ostream& os, uint128 v);
0250
0251
0252
0253 constexpr uint128 Uint128Max() {
0254 return uint128((std::numeric_limits<uint64_t>::max)(),
0255 (std::numeric_limits<uint64_t>::max)());
0256 }
0257
0258 ABSL_NAMESPACE_END
0259 }
0260
0261
0262 namespace std {
0263 template <>
0264 class numeric_limits<absl::uint128> {
0265 public:
0266 static constexpr bool is_specialized = true;
0267 static constexpr bool is_signed = false;
0268 static constexpr bool is_integer = true;
0269 static constexpr bool is_exact = true;
0270 static constexpr bool has_infinity = false;
0271 static constexpr bool has_quiet_NaN = false;
0272 static constexpr bool has_signaling_NaN = false;
0273 ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
0274 static constexpr float_denorm_style has_denorm = denorm_absent;
0275 ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
0276 static constexpr bool has_denorm_loss = false;
0277 static constexpr float_round_style round_style = round_toward_zero;
0278 static constexpr bool is_iec559 = false;
0279 static constexpr bool is_bounded = true;
0280 static constexpr bool is_modulo = true;
0281 static constexpr int digits = 128;
0282 static constexpr int digits10 = 38;
0283 static constexpr int max_digits10 = 0;
0284 static constexpr int radix = 2;
0285 static constexpr int min_exponent = 0;
0286 static constexpr int min_exponent10 = 0;
0287 static constexpr int max_exponent = 0;
0288 static constexpr int max_exponent10 = 0;
0289 #ifdef ABSL_HAVE_INTRINSIC_INT128
0290 static constexpr bool traps = numeric_limits<unsigned __int128>::traps;
0291 #else
0292 static constexpr bool traps = numeric_limits<uint64_t>::traps;
0293 #endif
0294 static constexpr bool tinyness_before = false;
0295
0296 static constexpr absl::uint128(min)() { return 0; }
0297 static constexpr absl::uint128 lowest() { return 0; }
0298 static constexpr absl::uint128(max)() { return absl::Uint128Max(); }
0299 static constexpr absl::uint128 epsilon() { return 0; }
0300 static constexpr absl::uint128 round_error() { return 0; }
0301 static constexpr absl::uint128 infinity() { return 0; }
0302 static constexpr absl::uint128 quiet_NaN() { return 0; }
0303 static constexpr absl::uint128 signaling_NaN() { return 0; }
0304 static constexpr absl::uint128 denorm_min() { return 0; }
0305 };
0306 }
0307
0308 namespace absl {
0309 ABSL_NAMESPACE_BEGIN
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345 class int128 {
0346 public:
0347 int128() = default;
0348
0349
0350 constexpr int128(int v);
0351 constexpr int128(unsigned int v);
0352 constexpr int128(long v);
0353 constexpr int128(unsigned long v);
0354 constexpr int128(long long v);
0355 constexpr int128(unsigned long long v);
0356 #ifdef ABSL_HAVE_INTRINSIC_INT128
0357 constexpr int128(__int128 v);
0358 constexpr explicit int128(unsigned __int128 v);
0359 #endif
0360 constexpr explicit int128(uint128 v);
0361 explicit int128(float v);
0362 explicit int128(double v);
0363 explicit int128(long double v);
0364
0365
0366 int128& operator=(int v);
0367 int128& operator=(unsigned int v);
0368 int128& operator=(long v);
0369 int128& operator=(unsigned long v);
0370 int128& operator=(long long v);
0371 int128& operator=(unsigned long long v);
0372 #ifdef ABSL_HAVE_INTRINSIC_INT128
0373 int128& operator=(__int128 v);
0374 #endif
0375
0376
0377 constexpr explicit operator bool() const;
0378 constexpr explicit operator char() const;
0379 constexpr explicit operator signed char() const;
0380 constexpr explicit operator unsigned char() const;
0381 constexpr explicit operator char16_t() const;
0382 constexpr explicit operator char32_t() const;
0383 constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const;
0384 constexpr explicit operator short() const;
0385
0386 constexpr explicit operator unsigned short() const;
0387 constexpr explicit operator int() const;
0388 constexpr explicit operator unsigned int() const;
0389 constexpr explicit operator long() const;
0390
0391 constexpr explicit operator unsigned long() const;
0392
0393 constexpr explicit operator long long() const;
0394
0395 constexpr explicit operator unsigned long long() const;
0396 #ifdef ABSL_HAVE_INTRINSIC_INT128
0397 constexpr explicit operator __int128() const;
0398 constexpr explicit operator unsigned __int128() const;
0399 #endif
0400 explicit operator float() const;
0401 explicit operator double() const;
0402 explicit operator long double() const;
0403
0404
0405
0406
0407 int128& operator+=(int128 other);
0408 int128& operator-=(int128 other);
0409 int128& operator*=(int128 other);
0410 int128& operator/=(int128 other);
0411 int128& operator%=(int128 other);
0412 int128 operator++(int);
0413 int128 operator--(int);
0414 int128& operator++();
0415 int128& operator--();
0416 int128& operator&=(int128 other);
0417 int128& operator|=(int128 other);
0418 int128& operator^=(int128 other);
0419 int128& operator<<=(int amount);
0420 int128& operator>>=(int amount);
0421
0422
0423
0424
0425 friend constexpr uint64_t Int128Low64(int128 v);
0426
0427
0428
0429
0430 friend constexpr int64_t Int128High64(int128 v);
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446 friend constexpr int128 MakeInt128(int64_t high, uint64_t low);
0447
0448
0449
0450
0451 friend constexpr int128 Int128Max();
0452
0453
0454
0455
0456 friend constexpr int128 Int128Min();
0457
0458
0459 template <typename H>
0460 friend H AbslHashValue(H h, int128 v) {
0461 return H::combine(std::move(h), Int128High64(v), Int128Low64(v));
0462 }
0463
0464
0465 template <typename Sink>
0466 friend void AbslStringify(Sink& sink, int128 v) {
0467 sink.Append(v.ToString());
0468 }
0469
0470 private:
0471 constexpr int128(int64_t high, uint64_t low);
0472
0473 std::string ToString() const;
0474
0475 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0476 __int128 v_;
0477 #else
0478 #if defined(ABSL_IS_LITTLE_ENDIAN)
0479 uint64_t lo_;
0480 int64_t hi_;
0481 #elif defined(ABSL_IS_BIG_ENDIAN)
0482 int64_t hi_;
0483 uint64_t lo_;
0484 #else
0485 #error "Unsupported byte order: must be little-endian or big-endian."
0486 #endif
0487 #endif
0488 };
0489
0490 std::ostream& operator<<(std::ostream& os, int128 v);
0491
0492
0493
0494 constexpr int128 Int128Max() {
0495 return int128((std::numeric_limits<int64_t>::max)(),
0496 (std::numeric_limits<uint64_t>::max)());
0497 }
0498
0499 constexpr int128 Int128Min() {
0500 return int128((std::numeric_limits<int64_t>::min)(), 0);
0501 }
0502
0503 ABSL_NAMESPACE_END
0504 }
0505
0506
0507 namespace std {
0508 template <>
0509 class numeric_limits<absl::int128> {
0510 public:
0511 static constexpr bool is_specialized = true;
0512 static constexpr bool is_signed = true;
0513 static constexpr bool is_integer = true;
0514 static constexpr bool is_exact = true;
0515 static constexpr bool has_infinity = false;
0516 static constexpr bool has_quiet_NaN = false;
0517 static constexpr bool has_signaling_NaN = false;
0518 ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
0519 static constexpr float_denorm_style has_denorm = denorm_absent;
0520 ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
0521 static constexpr bool has_denorm_loss = false;
0522 static constexpr float_round_style round_style = round_toward_zero;
0523 static constexpr bool is_iec559 = false;
0524 static constexpr bool is_bounded = true;
0525 static constexpr bool is_modulo = false;
0526 static constexpr int digits = 127;
0527 static constexpr int digits10 = 38;
0528 static constexpr int max_digits10 = 0;
0529 static constexpr int radix = 2;
0530 static constexpr int min_exponent = 0;
0531 static constexpr int min_exponent10 = 0;
0532 static constexpr int max_exponent = 0;
0533 static constexpr int max_exponent10 = 0;
0534 #ifdef ABSL_HAVE_INTRINSIC_INT128
0535 static constexpr bool traps = numeric_limits<__int128>::traps;
0536 #else
0537 static constexpr bool traps = numeric_limits<uint64_t>::traps;
0538 #endif
0539 static constexpr bool tinyness_before = false;
0540
0541 static constexpr absl::int128(min)() { return absl::Int128Min(); }
0542 static constexpr absl::int128 lowest() { return absl::Int128Min(); }
0543 static constexpr absl::int128(max)() { return absl::Int128Max(); }
0544 static constexpr absl::int128 epsilon() { return 0; }
0545 static constexpr absl::int128 round_error() { return 0; }
0546 static constexpr absl::int128 infinity() { return 0; }
0547 static constexpr absl::int128 quiet_NaN() { return 0; }
0548 static constexpr absl::int128 signaling_NaN() { return 0; }
0549 static constexpr absl::int128 denorm_min() { return 0; }
0550 };
0551 }
0552
0553
0554
0555
0556 namespace absl {
0557 ABSL_NAMESPACE_BEGIN
0558
0559 constexpr uint128 MakeUint128(uint64_t high, uint64_t low) {
0560 return uint128(high, low);
0561 }
0562
0563
0564
0565 inline uint128& uint128::operator=(int v) { return *this = uint128(v); }
0566
0567 inline uint128& uint128::operator=(unsigned int v) {
0568 return *this = uint128(v);
0569 }
0570
0571 inline uint128& uint128::operator=(long v) {
0572 return *this = uint128(v);
0573 }
0574
0575
0576 inline uint128& uint128::operator=(unsigned long v) {
0577 return *this = uint128(v);
0578 }
0579
0580
0581 inline uint128& uint128::operator=(long long v) { return *this = uint128(v); }
0582
0583
0584 inline uint128& uint128::operator=(unsigned long long v) {
0585 return *this = uint128(v);
0586 }
0587
0588 #ifdef ABSL_HAVE_INTRINSIC_INT128
0589 inline uint128& uint128::operator=(__int128 v) { return *this = uint128(v); }
0590
0591 inline uint128& uint128::operator=(unsigned __int128 v) {
0592 return *this = uint128(v);
0593 }
0594 #endif
0595
0596 inline uint128& uint128::operator=(int128 v) { return *this = uint128(v); }
0597
0598
0599
0600 constexpr uint128 operator<<(uint128 lhs, int amount);
0601 constexpr uint128 operator>>(uint128 lhs, int amount);
0602 constexpr uint128 operator+(uint128 lhs, uint128 rhs);
0603 constexpr uint128 operator-(uint128 lhs, uint128 rhs);
0604 uint128 operator*(uint128 lhs, uint128 rhs);
0605 uint128 operator/(uint128 lhs, uint128 rhs);
0606 uint128 operator%(uint128 lhs, uint128 rhs);
0607
0608 inline uint128& uint128::operator<<=(int amount) {
0609 *this = *this << amount;
0610 return *this;
0611 }
0612
0613 inline uint128& uint128::operator>>=(int amount) {
0614 *this = *this >> amount;
0615 return *this;
0616 }
0617
0618 inline uint128& uint128::operator+=(uint128 other) {
0619 *this = *this + other;
0620 return *this;
0621 }
0622
0623 inline uint128& uint128::operator-=(uint128 other) {
0624 *this = *this - other;
0625 return *this;
0626 }
0627
0628 inline uint128& uint128::operator*=(uint128 other) {
0629 *this = *this * other;
0630 return *this;
0631 }
0632
0633 inline uint128& uint128::operator/=(uint128 other) {
0634 *this = *this / other;
0635 return *this;
0636 }
0637
0638 inline uint128& uint128::operator%=(uint128 other) {
0639 *this = *this % other;
0640 return *this;
0641 }
0642
0643 constexpr uint64_t Uint128Low64(uint128 v) { return v.lo_; }
0644
0645 constexpr uint64_t Uint128High64(uint128 v) { return v.hi_; }
0646
0647
0648
0649 #if defined(ABSL_IS_LITTLE_ENDIAN)
0650
0651 constexpr uint128::uint128(uint64_t high, uint64_t low) : lo_{low}, hi_{high} {}
0652
0653 constexpr uint128::uint128(int v)
0654 : lo_{static_cast<uint64_t>(v)},
0655 hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
0656 constexpr uint128::uint128(long v)
0657 : lo_{static_cast<uint64_t>(v)},
0658 hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
0659 constexpr uint128::uint128(long long v)
0660 : lo_{static_cast<uint64_t>(v)},
0661 hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
0662
0663 constexpr uint128::uint128(unsigned int v) : lo_{v}, hi_{0} {}
0664
0665 constexpr uint128::uint128(unsigned long v) : lo_{v}, hi_{0} {}
0666
0667 constexpr uint128::uint128(unsigned long long v) : lo_{v}, hi_{0} {}
0668
0669 #ifdef ABSL_HAVE_INTRINSIC_INT128
0670 constexpr uint128::uint128(__int128 v)
0671 : lo_{static_cast<uint64_t>(v & ~uint64_t{0})},
0672 hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)} {}
0673 constexpr uint128::uint128(unsigned __int128 v)
0674 : lo_{static_cast<uint64_t>(v & ~uint64_t{0})},
0675 hi_{static_cast<uint64_t>(v >> 64)} {}
0676 #endif
0677
0678 constexpr uint128::uint128(int128 v)
0679 : lo_{Int128Low64(v)}, hi_{static_cast<uint64_t>(Int128High64(v))} {}
0680
0681 #elif defined(ABSL_IS_BIG_ENDIAN)
0682
0683 constexpr uint128::uint128(uint64_t high, uint64_t low) : hi_{high}, lo_{low} {}
0684
0685 constexpr uint128::uint128(int v)
0686 : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
0687 lo_{static_cast<uint64_t>(v)} {}
0688 constexpr uint128::uint128(long v)
0689 : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
0690 lo_{static_cast<uint64_t>(v)} {}
0691 constexpr uint128::uint128(long long v)
0692 : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
0693 lo_{static_cast<uint64_t>(v)} {}
0694
0695 constexpr uint128::uint128(unsigned int v) : hi_{0}, lo_{v} {}
0696
0697 constexpr uint128::uint128(unsigned long v) : hi_{0}, lo_{v} {}
0698
0699 constexpr uint128::uint128(unsigned long long v) : hi_{0}, lo_{v} {}
0700
0701 #ifdef ABSL_HAVE_INTRINSIC_INT128
0702 constexpr uint128::uint128(__int128 v)
0703 : hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)},
0704 lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {}
0705 constexpr uint128::uint128(unsigned __int128 v)
0706 : hi_{static_cast<uint64_t>(v >> 64)},
0707 lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {}
0708 #endif
0709
0710 constexpr uint128::uint128(int128 v)
0711 : hi_{static_cast<uint64_t>(Int128High64(v))}, lo_{Int128Low64(v)} {}
0712
0713 #else
0714 #error "Unsupported byte order: must be little-endian or big-endian."
0715 #endif
0716
0717
0718
0719 constexpr uint128::operator bool() const { return lo_ || hi_; }
0720
0721 constexpr uint128::operator char() const { return static_cast<char>(lo_); }
0722
0723 constexpr uint128::operator signed char() const {
0724 return static_cast<signed char>(lo_);
0725 }
0726
0727 constexpr uint128::operator unsigned char() const {
0728 return static_cast<unsigned char>(lo_);
0729 }
0730
0731 constexpr uint128::operator char16_t() const {
0732 return static_cast<char16_t>(lo_);
0733 }
0734
0735 constexpr uint128::operator char32_t() const {
0736 return static_cast<char32_t>(lo_);
0737 }
0738
0739 constexpr uint128::operator ABSL_INTERNAL_WCHAR_T() const {
0740 return static_cast<ABSL_INTERNAL_WCHAR_T>(lo_);
0741 }
0742
0743
0744 constexpr uint128::operator short() const { return static_cast<short>(lo_); }
0745
0746 constexpr uint128::operator unsigned short() const {
0747 return static_cast<unsigned short>(lo_);
0748 }
0749
0750 constexpr uint128::operator int() const { return static_cast<int>(lo_); }
0751
0752 constexpr uint128::operator unsigned int() const {
0753 return static_cast<unsigned int>(lo_);
0754 }
0755
0756
0757 constexpr uint128::operator long() const { return static_cast<long>(lo_); }
0758
0759 constexpr uint128::operator unsigned long() const {
0760 return static_cast<unsigned long>(lo_);
0761 }
0762
0763 constexpr uint128::operator long long() const {
0764 return static_cast<long long>(lo_);
0765 }
0766
0767 constexpr uint128::operator unsigned long long() const {
0768 return static_cast<unsigned long long>(lo_);
0769 }
0770
0771 #ifdef ABSL_HAVE_INTRINSIC_INT128
0772 constexpr uint128::operator __int128() const {
0773 return (static_cast<__int128>(hi_) << 64) + lo_;
0774 }
0775
0776 constexpr uint128::operator unsigned __int128() const {
0777 return (static_cast<unsigned __int128>(hi_) << 64) + lo_;
0778 }
0779 #endif
0780
0781
0782
0783 inline uint128::operator float() const {
0784 return static_cast<float>(lo_) + std::ldexp(static_cast<float>(hi_), 64);
0785 }
0786
0787 inline uint128::operator double() const {
0788 return static_cast<double>(lo_) + std::ldexp(static_cast<double>(hi_), 64);
0789 }
0790
0791 inline uint128::operator long double() const {
0792 return static_cast<long double>(lo_) +
0793 std::ldexp(static_cast<long double>(hi_), 64);
0794 }
0795
0796
0797
0798 constexpr bool operator==(uint128 lhs, uint128 rhs) {
0799 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0800 return static_cast<unsigned __int128>(lhs) ==
0801 static_cast<unsigned __int128>(rhs);
0802 #else
0803 return (Uint128Low64(lhs) == Uint128Low64(rhs) &&
0804 Uint128High64(lhs) == Uint128High64(rhs));
0805 #endif
0806 }
0807
0808 constexpr bool operator!=(uint128 lhs, uint128 rhs) { return !(lhs == rhs); }
0809
0810 constexpr bool operator<(uint128 lhs, uint128 rhs) {
0811 #ifdef ABSL_HAVE_INTRINSIC_INT128
0812 return static_cast<unsigned __int128>(lhs) <
0813 static_cast<unsigned __int128>(rhs);
0814 #else
0815 return (Uint128High64(lhs) == Uint128High64(rhs))
0816 ? (Uint128Low64(lhs) < Uint128Low64(rhs))
0817 : (Uint128High64(lhs) < Uint128High64(rhs));
0818 #endif
0819 }
0820
0821 constexpr bool operator>(uint128 lhs, uint128 rhs) { return rhs < lhs; }
0822
0823 constexpr bool operator<=(uint128 lhs, uint128 rhs) { return !(rhs < lhs); }
0824
0825 constexpr bool operator>=(uint128 lhs, uint128 rhs) { return !(lhs < rhs); }
0826
0827 #ifdef __cpp_impl_three_way_comparison
0828 constexpr absl::strong_ordering operator<=>(uint128 lhs, uint128 rhs) {
0829 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0830 if (auto lhs_128 = static_cast<unsigned __int128>(lhs),
0831 rhs_128 = static_cast<unsigned __int128>(rhs);
0832 lhs_128 < rhs_128) {
0833 return absl::strong_ordering::less;
0834 } else if (lhs_128 > rhs_128) {
0835 return absl::strong_ordering::greater;
0836 } else {
0837 return absl::strong_ordering::equal;
0838 }
0839 #else
0840 if (uint64_t lhs_high = Uint128High64(lhs), rhs_high = Uint128High64(rhs);
0841 lhs_high < rhs_high) {
0842 return absl::strong_ordering::less;
0843 } else if (lhs_high > rhs_high) {
0844 return absl::strong_ordering::greater;
0845 } else if (uint64_t lhs_low = Uint128Low64(lhs), rhs_low = Uint128Low64(rhs);
0846 lhs_low < rhs_low) {
0847 return absl::strong_ordering::less;
0848 } else if (lhs_low > rhs_low) {
0849 return absl::strong_ordering::greater;
0850 } else {
0851 return absl::strong_ordering::equal;
0852 }
0853 #endif
0854 }
0855 #endif
0856
0857
0858
0859 constexpr inline uint128 operator+(uint128 val) { return val; }
0860
0861 constexpr inline int128 operator+(int128 val) { return val; }
0862
0863 constexpr uint128 operator-(uint128 val) {
0864 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0865 return -static_cast<unsigned __int128>(val);
0866 #else
0867 return MakeUint128(
0868 ~Uint128High64(val) + static_cast<unsigned long>(Uint128Low64(val) == 0),
0869 ~Uint128Low64(val) + 1);
0870 #endif
0871 }
0872
0873 constexpr inline bool operator!(uint128 val) {
0874 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0875 return !static_cast<unsigned __int128>(val);
0876 #else
0877 return !Uint128High64(val) && !Uint128Low64(val);
0878 #endif
0879 }
0880
0881
0882
0883 constexpr inline uint128 operator~(uint128 val) {
0884 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0885 return ~static_cast<unsigned __int128>(val);
0886 #else
0887 return MakeUint128(~Uint128High64(val), ~Uint128Low64(val));
0888 #endif
0889 }
0890
0891 constexpr inline uint128 operator|(uint128 lhs, uint128 rhs) {
0892 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0893 return static_cast<unsigned __int128>(lhs) |
0894 static_cast<unsigned __int128>(rhs);
0895 #else
0896 return MakeUint128(Uint128High64(lhs) | Uint128High64(rhs),
0897 Uint128Low64(lhs) | Uint128Low64(rhs));
0898 #endif
0899 }
0900
0901 constexpr inline uint128 operator&(uint128 lhs, uint128 rhs) {
0902 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0903 return static_cast<unsigned __int128>(lhs) &
0904 static_cast<unsigned __int128>(rhs);
0905 #else
0906 return MakeUint128(Uint128High64(lhs) & Uint128High64(rhs),
0907 Uint128Low64(lhs) & Uint128Low64(rhs));
0908 #endif
0909 }
0910
0911 constexpr inline uint128 operator^(uint128 lhs, uint128 rhs) {
0912 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0913 return static_cast<unsigned __int128>(lhs) ^
0914 static_cast<unsigned __int128>(rhs);
0915 #else
0916 return MakeUint128(Uint128High64(lhs) ^ Uint128High64(rhs),
0917 Uint128Low64(lhs) ^ Uint128Low64(rhs));
0918 #endif
0919 }
0920
0921 inline uint128& uint128::operator|=(uint128 other) {
0922 *this = *this | other;
0923 return *this;
0924 }
0925
0926 inline uint128& uint128::operator&=(uint128 other) {
0927 *this = *this & other;
0928 return *this;
0929 }
0930
0931 inline uint128& uint128::operator^=(uint128 other) {
0932 *this = *this ^ other;
0933 return *this;
0934 }
0935
0936
0937
0938 constexpr uint128 operator<<(uint128 lhs, int amount) {
0939 #ifdef ABSL_HAVE_INTRINSIC_INT128
0940 return static_cast<unsigned __int128>(lhs) << amount;
0941 #else
0942
0943
0944 return amount >= 64 ? MakeUint128(Uint128Low64(lhs) << (amount - 64), 0)
0945 : amount == 0 ? lhs
0946 : MakeUint128((Uint128High64(lhs) << amount) |
0947 (Uint128Low64(lhs) >> (64 - amount)),
0948 Uint128Low64(lhs) << amount);
0949 #endif
0950 }
0951
0952 constexpr uint128 operator>>(uint128 lhs, int amount) {
0953 #ifdef ABSL_HAVE_INTRINSIC_INT128
0954 return static_cast<unsigned __int128>(lhs) >> amount;
0955 #else
0956
0957
0958 return amount >= 64 ? MakeUint128(0, Uint128High64(lhs) >> (amount - 64))
0959 : amount == 0 ? lhs
0960 : MakeUint128(Uint128High64(lhs) >> amount,
0961 (Uint128Low64(lhs) >> amount) |
0962 (Uint128High64(lhs) << (64 - amount)));
0963 #endif
0964 }
0965
0966 #if !defined(ABSL_HAVE_INTRINSIC_INT128)
0967 namespace int128_internal {
0968 constexpr uint128 AddResult(uint128 result, uint128 lhs) {
0969
0970 return (Uint128Low64(result) < Uint128Low64(lhs))
0971 ? MakeUint128(Uint128High64(result) + 1, Uint128Low64(result))
0972 : result;
0973 }
0974 }
0975 #endif
0976
0977 constexpr uint128 operator+(uint128 lhs, uint128 rhs) {
0978 #if defined(ABSL_HAVE_INTRINSIC_INT128)
0979 return static_cast<unsigned __int128>(lhs) +
0980 static_cast<unsigned __int128>(rhs);
0981 #else
0982 return int128_internal::AddResult(
0983 MakeUint128(Uint128High64(lhs) + Uint128High64(rhs),
0984 Uint128Low64(lhs) + Uint128Low64(rhs)),
0985 lhs);
0986 #endif
0987 }
0988
0989 #if !defined(ABSL_HAVE_INTRINSIC_INT128)
0990 namespace int128_internal {
0991 constexpr uint128 SubstructResult(uint128 result, uint128 lhs, uint128 rhs) {
0992
0993 return (Uint128Low64(lhs) < Uint128Low64(rhs))
0994 ? MakeUint128(Uint128High64(result) - 1, Uint128Low64(result))
0995 : result;
0996 }
0997 }
0998 #endif
0999
1000 constexpr uint128 operator-(uint128 lhs, uint128 rhs) {
1001 #if defined(ABSL_HAVE_INTRINSIC_INT128)
1002 return static_cast<unsigned __int128>(lhs) -
1003 static_cast<unsigned __int128>(rhs);
1004 #else
1005 return int128_internal::SubstructResult(
1006 MakeUint128(Uint128High64(lhs) - Uint128High64(rhs),
1007 Uint128Low64(lhs) - Uint128Low64(rhs)),
1008 lhs, rhs);
1009 #endif
1010 }
1011
1012 inline uint128 operator*(uint128 lhs, uint128 rhs) {
1013 #if defined(ABSL_HAVE_INTRINSIC_INT128)
1014
1015
1016 return static_cast<unsigned __int128>(lhs) *
1017 static_cast<unsigned __int128>(rhs);
1018 #elif defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC)
1019 uint64_t carry;
1020 uint64_t low = _umul128(Uint128Low64(lhs), Uint128Low64(rhs), &carry);
1021 return MakeUint128(Uint128Low64(lhs) * Uint128High64(rhs) +
1022 Uint128High64(lhs) * Uint128Low64(rhs) + carry,
1023 low);
1024 #else
1025 uint64_t a32 = Uint128Low64(lhs) >> 32;
1026 uint64_t a00 = Uint128Low64(lhs) & 0xffffffff;
1027 uint64_t b32 = Uint128Low64(rhs) >> 32;
1028 uint64_t b00 = Uint128Low64(rhs) & 0xffffffff;
1029 uint128 result =
1030 MakeUint128(Uint128High64(lhs) * Uint128Low64(rhs) +
1031 Uint128Low64(lhs) * Uint128High64(rhs) + a32 * b32,
1032 a00 * b00);
1033 result += uint128(a32 * b00) << 32;
1034 result += uint128(a00 * b32) << 32;
1035 return result;
1036 #endif
1037 }
1038
1039 #if defined(ABSL_HAVE_INTRINSIC_INT128)
1040 inline uint128 operator/(uint128 lhs, uint128 rhs) {
1041 return static_cast<unsigned __int128>(lhs) /
1042 static_cast<unsigned __int128>(rhs);
1043 }
1044
1045 inline uint128 operator%(uint128 lhs, uint128 rhs) {
1046 return static_cast<unsigned __int128>(lhs) %
1047 static_cast<unsigned __int128>(rhs);
1048 }
1049 #endif
1050
1051
1052
1053 inline uint128 uint128::operator++(int) {
1054 uint128 tmp(*this);
1055 *this += 1;
1056 return tmp;
1057 }
1058
1059 inline uint128 uint128::operator--(int) {
1060 uint128 tmp(*this);
1061 *this -= 1;
1062 return tmp;
1063 }
1064
1065 inline uint128& uint128::operator++() {
1066 *this += 1;
1067 return *this;
1068 }
1069
1070 inline uint128& uint128::operator--() {
1071 *this -= 1;
1072 return *this;
1073 }
1074
1075 constexpr int128 MakeInt128(int64_t high, uint64_t low) {
1076 return int128(high, low);
1077 }
1078
1079
1080 inline int128& int128::operator=(int v) { return *this = int128(v); }
1081
1082 inline int128& int128::operator=(unsigned int v) { return *this = int128(v); }
1083
1084 inline int128& int128::operator=(long v) {
1085 return *this = int128(v);
1086 }
1087
1088
1089 inline int128& int128::operator=(unsigned long v) { return *this = int128(v); }
1090
1091
1092 inline int128& int128::operator=(long long v) { return *this = int128(v); }
1093
1094
1095 inline int128& int128::operator=(unsigned long long v) {
1096 return *this = int128(v);
1097 }
1098
1099
1100 constexpr int128 operator-(int128 v);
1101 constexpr int128 operator+(int128 lhs, int128 rhs);
1102 constexpr int128 operator-(int128 lhs, int128 rhs);
1103 int128 operator*(int128 lhs, int128 rhs);
1104 int128 operator/(int128 lhs, int128 rhs);
1105 int128 operator%(int128 lhs, int128 rhs);
1106 constexpr int128 operator|(int128 lhs, int128 rhs);
1107 constexpr int128 operator&(int128 lhs, int128 rhs);
1108 constexpr int128 operator^(int128 lhs, int128 rhs);
1109 constexpr int128 operator<<(int128 lhs, int amount);
1110 constexpr int128 operator>>(int128 lhs, int amount);
1111
1112 inline int128& int128::operator+=(int128 other) {
1113 *this = *this + other;
1114 return *this;
1115 }
1116
1117 inline int128& int128::operator-=(int128 other) {
1118 *this = *this - other;
1119 return *this;
1120 }
1121
1122 inline int128& int128::operator*=(int128 other) {
1123 *this = *this * other;
1124 return *this;
1125 }
1126
1127 inline int128& int128::operator/=(int128 other) {
1128 *this = *this / other;
1129 return *this;
1130 }
1131
1132 inline int128& int128::operator%=(int128 other) {
1133 *this = *this % other;
1134 return *this;
1135 }
1136
1137 inline int128& int128::operator|=(int128 other) {
1138 *this = *this | other;
1139 return *this;
1140 }
1141
1142 inline int128& int128::operator&=(int128 other) {
1143 *this = *this & other;
1144 return *this;
1145 }
1146
1147 inline int128& int128::operator^=(int128 other) {
1148 *this = *this ^ other;
1149 return *this;
1150 }
1151
1152 inline int128& int128::operator<<=(int amount) {
1153 *this = *this << amount;
1154 return *this;
1155 }
1156
1157 inline int128& int128::operator>>=(int amount) {
1158 *this = *this >> amount;
1159 return *this;
1160 }
1161
1162
1163 constexpr bool operator!=(int128 lhs, int128 rhs);
1164
1165 namespace int128_internal {
1166
1167
1168
1169 constexpr int64_t BitCastToSigned(uint64_t v) {
1170
1171
1172
1173
1174
1175 return v & (uint64_t{1} << 63) ? ~static_cast<int64_t>(~v)
1176 : static_cast<int64_t>(v);
1177 }
1178
1179 }
1180
1181 #if defined(ABSL_HAVE_INTRINSIC_INT128)
1182 #include "absl/numeric/int128_have_intrinsic.inc" // IWYU pragma: export
1183 #else
1184 #include "absl/numeric/int128_no_intrinsic.inc" // IWYU pragma: export
1185 #endif
1186
1187 ABSL_NAMESPACE_END
1188 }
1189
1190 #undef ABSL_INTERNAL_WCHAR_T
1191
1192 #endif