22 #ifndef ABSL_NUMERIC_INT128_H_
23 #define ABSL_NUMERIC_INT128_H_
33 #include "absl/base/config.h"
34 #include "absl/base/macros.h"
35 #include "absl/base/port.h"
42 #define ABSL_INTERNAL_WCHAR_T __wchar_t
45 #pragma intrinsic(_umul128)
46 #endif // defined(_M_X64)
47 #else // defined(_MSC_VER)
48 #define ABSL_INTERNAL_WCHAR_T wchar_t
49 #endif // defined(_MSC_VER)
101 #if defined(ABSL_HAVE_INTRINSIC_INT128)
102 alignas(
unsigned __int128)
109 constexpr uint128(
int v);
110 constexpr uint128(
unsigned int v);
111 constexpr uint128(
long v);
112 constexpr uint128(
unsigned long v);
113 constexpr uint128(
long long v);
114 constexpr uint128(
unsigned long long v);
115 #ifdef ABSL_HAVE_INTRINSIC_INT128
116 constexpr uint128(__int128
v);
117 constexpr uint128(
unsigned __int128
v);
118 #endif // ABSL_HAVE_INTRINSIC_INT128
119 constexpr uint128(int128
v);
120 explicit uint128(
float v);
121 explicit uint128(
double v);
122 explicit uint128(
long double v);
125 uint128& operator=(
int v);
126 uint128& operator=(
unsigned int v);
127 uint128& operator=(
long v);
128 uint128& operator=(
unsigned long v);
129 uint128& operator=(
long long v);
130 uint128& operator=(
unsigned long long v);
131 #ifdef ABSL_HAVE_INTRINSIC_INT128
132 uint128& operator=(__int128
v);
133 uint128& operator=(
unsigned __int128
v);
134 #endif // ABSL_HAVE_INTRINSIC_INT128
135 uint128& operator=(int128
v);
138 constexpr
explicit operator bool()
const;
139 constexpr
explicit operator char()
const;
140 constexpr
explicit operator signed char()
const;
141 constexpr
explicit operator unsigned char()
const;
142 constexpr
explicit operator char16_t()
const;
143 constexpr
explicit operator char32_t()
const;
145 constexpr
explicit operator short()
const;
147 constexpr
explicit operator unsigned short()
const;
148 constexpr
explicit operator int()
const;
149 constexpr
explicit operator unsigned int()
const;
150 constexpr
explicit operator long()
const;
152 constexpr
explicit operator unsigned long()
const;
154 constexpr
explicit operator long long()
const;
156 constexpr
explicit operator unsigned long long()
const;
157 #ifdef ABSL_HAVE_INTRINSIC_INT128
158 constexpr
explicit operator __int128()
const;
159 constexpr
explicit operator unsigned __int128()
const;
160 #endif // ABSL_HAVE_INTRINSIC_INT128
161 explicit operator float()
const;
162 explicit operator double()
const;
163 explicit operator long double()
const;
175 uint128 operator--(
int);
176 uint128& operator<<=(
int);
177 uint128& operator>>=(
int);
182 uint128& operator--();
211 template <
typename H>
223 #if defined(ABSL_IS_LITTLE_ENDIAN)
226 #elif defined(ABSL_IS_BIG_ENDIAN)
230 #error "Unsupported byte order: must be little-endian or big-endian."
240 std::ostream&
operator<<(std::ostream& os, uint128
v);
255 class numeric_limits<
absl::uint128> {
257 static constexpr
bool is_specialized =
true;
258 static constexpr
bool is_signed =
false;
259 static constexpr
bool is_integer =
true;
260 static constexpr
bool is_exact =
true;
261 static constexpr
bool has_infinity =
false;
262 static constexpr
bool has_quiet_NaN =
false;
263 static constexpr
bool has_signaling_NaN =
false;
264 static constexpr float_denorm_style has_denorm = denorm_absent;
265 static constexpr
bool has_denorm_loss =
false;
266 static constexpr float_round_style round_style = round_toward_zero;
267 static constexpr
bool is_iec559 =
false;
268 static constexpr
bool is_bounded =
true;
269 static constexpr
bool is_modulo =
true;
270 static constexpr
int digits = 128;
271 static constexpr
int digits10 = 38;
272 static constexpr
int max_digits10 = 0;
273 static constexpr
int radix = 2;
275 static constexpr
int min_exponent10 = 0;
276 static constexpr
int max_exponent = 0;
277 static constexpr
int max_exponent10 = 0;
278 #ifdef ABSL_HAVE_INTRINSIC_INT128
279 static constexpr
bool traps = numeric_limits<unsigned __int128>::traps;
280 #else // ABSL_HAVE_INTRINSIC_INT128
281 static constexpr
bool traps = numeric_limits<uint64_t>::traps;
282 #endif // ABSL_HAVE_INTRINSIC_INT128
283 static constexpr
bool tinyness_before =
false;
340 constexpr
int128(
unsigned int v);
342 constexpr
int128(
unsigned long v);
344 constexpr
int128(
unsigned long long v);
345 #ifdef ABSL_HAVE_INTRINSIC_INT128
347 constexpr
explicit int128(
unsigned __int128
v);
348 #endif // ABSL_HAVE_INTRINSIC_INT128
349 constexpr
explicit int128(uint128
v);
352 explicit int128(
long double v);
361 #ifdef ABSL_HAVE_INTRINSIC_INT128
363 #endif // ABSL_HAVE_INTRINSIC_INT128
366 constexpr
explicit operator bool()
const;
367 constexpr
explicit operator char()
const;
368 constexpr
explicit operator signed char()
const;
369 constexpr
explicit operator unsigned char()
const;
370 constexpr
explicit operator char16_t()
const;
371 constexpr
explicit operator char32_t()
const;
373 constexpr
explicit operator short()
const;
375 constexpr
explicit operator unsigned short()
const;
376 constexpr
explicit operator int()
const;
377 constexpr
explicit operator unsigned int()
const;
378 constexpr
explicit operator long()
const;
380 constexpr
explicit operator unsigned long()
const;
382 constexpr
explicit operator long long()
const;
384 constexpr
explicit operator unsigned long long()
const;
385 #ifdef ABSL_HAVE_INTRINSIC_INT128
386 constexpr
explicit operator __int128()
const;
387 constexpr
explicit operator unsigned __int128()
const;
388 #endif // ABSL_HAVE_INTRINSIC_INT128
389 explicit operator float()
const;
390 explicit operator double()
const;
391 explicit operator long double()
const;
448 template <
typename H>
456 #if defined(ABSL_HAVE_INTRINSIC_INT128)
458 #else // ABSL_HAVE_INTRINSIC_INT128
459 #if defined(ABSL_IS_LITTLE_ENDIAN)
462 #elif defined(ABSL_IS_BIG_ENDIAN)
466 #error "Unsupported byte order: must be little-endian or big-endian."
468 #endif // ABSL_HAVE_INTRINSIC_INT128
471 std::ostream&
operator<<(std::ostream& os, int128
v);
490 class numeric_limits<
absl::int128> {
492 static constexpr
bool is_specialized =
true;
493 static constexpr
bool is_signed =
true;
494 static constexpr
bool is_integer =
true;
495 static constexpr
bool is_exact =
true;
496 static constexpr
bool has_infinity =
false;
497 static constexpr
bool has_quiet_NaN =
false;
498 static constexpr
bool has_signaling_NaN =
false;
499 static constexpr float_denorm_style has_denorm = denorm_absent;
500 static constexpr
bool has_denorm_loss =
false;
501 static constexpr float_round_style round_style = round_toward_zero;
502 static constexpr
bool is_iec559 =
false;
503 static constexpr
bool is_bounded =
true;
504 static constexpr
bool is_modulo =
false;
505 static constexpr
int digits = 127;
506 static constexpr
int digits10 = 38;
507 static constexpr
int max_digits10 = 0;
508 static constexpr
int radix = 2;
510 static constexpr
int min_exponent10 = 0;
511 static constexpr
int max_exponent = 0;
512 static constexpr
int max_exponent10 = 0;
513 #ifdef ABSL_HAVE_INTRINSIC_INT128
514 static constexpr
bool traps = numeric_limits<__int128>::traps;
515 #else // ABSL_HAVE_INTRINSIC_INT128
516 static constexpr
bool traps = numeric_limits<uint64_t>::traps;
517 #endif // ABSL_HAVE_INTRINSIC_INT128
518 static constexpr
bool tinyness_before =
false;
539 return uint128(high, low);
569 #ifdef ABSL_HAVE_INTRINSIC_INT128
577 #endif // ABSL_HAVE_INTRINSIC_INT128
587 uint128
operator+(uint128 lhs, uint128 rhs);
588 uint128
operator-(uint128 lhs, uint128 rhs);
589 uint128
operator*(uint128 lhs, uint128 rhs);
590 uint128
operator/(uint128 lhs, uint128 rhs);
591 uint128
operator%(uint128 lhs, uint128 rhs);
594 *
this = *
this << amount;
599 *
this = *
this >> amount;
604 *
this = *
this + other;
609 *
this = *
this - other;
614 *
this = *
this * other;
619 *
this = *
this / other;
624 *
this = *
this % other;
634 #if defined(ABSL_IS_LITTLE_ENDIAN)
637 : lo_{low}, hi_{high} {}
639 constexpr uint128::uint128(
int v)
642 constexpr uint128::uint128(
long v)
645 constexpr uint128::uint128(
long long v)
649 constexpr uint128::uint128(
unsigned int v) : lo_{
v}, hi_{0} {}
651 constexpr uint128::uint128(
unsigned long v) : lo_{
v}, hi_{0} {}
653 constexpr uint128::uint128(
unsigned long long v) : lo_{
v}, hi_{0} {}
655 #ifdef ABSL_HAVE_INTRINSIC_INT128
656 constexpr uint128::uint128(__int128
v)
658 hi_{
static_cast<uint64_t>(
static_cast<unsigned __int128
>(
v) >> 64)} {}
659 constexpr uint128::uint128(
unsigned __int128
v)
662 #endif // ABSL_HAVE_INTRINSIC_INT128
664 constexpr uint128::uint128(int128
v)
665 : lo_{Int128Low64(
v)}, hi_{
static_cast<uint64_t>(Int128High64(
v))} {}
667 #elif defined(ABSL_IS_BIG_ENDIAN)
670 : hi_{high}, lo_{low} {}
672 constexpr uint128::uint128(
int v)
675 constexpr uint128::uint128(
long v)
678 constexpr uint128::uint128(
long long v)
682 constexpr uint128::uint128(
unsigned int v) : hi_{0}, lo_{
v} {}
684 constexpr uint128::uint128(
unsigned long v) : hi_{0}, lo_{
v} {}
686 constexpr uint128::uint128(
unsigned long long v) : hi_{0}, lo_{
v} {}
688 #ifdef ABSL_HAVE_INTRINSIC_INT128
689 constexpr uint128::uint128(__int128
v)
690 : hi_{
static_cast<uint64_t>(
static_cast<unsigned __int128
>(
v) >> 64)},
692 constexpr uint128::uint128(
unsigned __int128
v)
695 #endif // ABSL_HAVE_INTRINSIC_INT128
697 constexpr uint128::uint128(int128
v)
698 : hi_{
static_cast<uint64_t>(Int128High64(
v))}, lo_{Int128Low64(
v)} {}
701 #error "Unsupported byte order: must be little-endian or big-endian."
706 constexpr uint128::operator
bool()
const {
return lo_ || hi_; }
708 constexpr uint128::operator char()
const {
return static_cast<char>(lo_); }
710 constexpr uint128::operator
signed char()
const {
711 return static_cast<signed char>(lo_);
714 constexpr uint128::operator
unsigned char()
const {
715 return static_cast<unsigned char>(lo_);
718 constexpr uint128::operator char16_t()
const {
719 return static_cast<char16_t
>(lo_);
722 constexpr uint128::operator char32_t()
const {
723 return static_cast<char32_t
>(lo_);
731 constexpr uint128::operator short()
const {
return static_cast<short>(lo_); }
733 constexpr uint128::operator
unsigned short()
const {
734 return static_cast<unsigned short>(lo_);
737 constexpr uint128::operator
int()
const {
return static_cast<int>(lo_); }
739 constexpr uint128::operator
unsigned int()
const {
740 return static_cast<unsigned int>(lo_);
744 constexpr uint128::operator
long()
const {
return static_cast<long>(lo_); }
746 constexpr uint128::operator
unsigned long()
const {
747 return static_cast<unsigned long>(lo_);
750 constexpr uint128::operator
long long()
const {
751 return static_cast<long long>(lo_);
754 constexpr uint128::operator
unsigned long long()
const {
755 return static_cast<unsigned long long>(lo_);
758 #ifdef ABSL_HAVE_INTRINSIC_INT128
759 constexpr uint128::operator __int128()
const {
760 return (
static_cast<__int128
>(hi_) << 64) + lo_;
763 constexpr uint128::operator
unsigned __int128()
const {
764 return (
static_cast<unsigned __int128
>(hi_) << 64) + lo_;
766 #endif // ABSL_HAVE_INTRINSIC_INT128
770 inline uint128::operator float()
const {
771 return static_cast<float>(lo_) + std::ldexp(
static_cast<float>(hi_), 64);
774 inline uint128::operator double()
const {
775 return static_cast<double>(lo_) + std::ldexp(
static_cast<double>(hi_), 64);
778 inline uint128::operator
long double()
const {
779 return static_cast<long double>(lo_) +
780 std::ldexp(
static_cast<long double>(hi_), 64);
785 inline bool operator==(uint128 lhs, uint128 rhs) {
790 inline bool operator!=(uint128 lhs, uint128 rhs) {
791 return !(lhs == rhs);
794 inline bool operator<(uint128 lhs, uint128 rhs) {
795 #ifdef ABSL_HAVE_INTRINSIC_INT128
796 return static_cast<unsigned __int128
>(lhs) <
797 static_cast<unsigned __int128
>(rhs);
805 inline bool operator>(uint128 lhs, uint128 rhs) {
return rhs < lhs; }
807 inline bool operator<=(uint128 lhs, uint128 rhs) {
return !(rhs < lhs); }
809 inline bool operator>=(uint128 lhs, uint128 rhs) {
return !(lhs < rhs); }
820 constexpr
inline bool operator!(uint128 val) {
826 constexpr
inline uint128
operator~(uint128 val) {
830 constexpr
inline uint128
operator|(uint128 lhs, uint128 rhs) {
835 constexpr
inline uint128
operator&(uint128 lhs, uint128 rhs) {
840 constexpr
inline uint128
operator^(uint128 lhs, uint128 rhs) {
865 inline uint128
operator<<(uint128 lhs,
int amount) {
866 #ifdef ABSL_HAVE_INTRINSIC_INT128
867 return static_cast<unsigned __int128
>(lhs) << amount;
883 inline uint128
operator>>(uint128 lhs,
int amount) {
884 #ifdef ABSL_HAVE_INTRINSIC_INT128
885 return static_cast<unsigned __int128
>(lhs) >> amount;
901 inline uint128
operator+(uint128 lhs, uint128 rhs) {
910 inline uint128
operator-(uint128 lhs, uint128 rhs) {
919 inline uint128
operator*(uint128 lhs, uint128 rhs) {
920 #if defined(ABSL_HAVE_INTRINSIC_INT128)
923 return static_cast<unsigned __int128
>(lhs) *
924 static_cast<unsigned __int128
>(rhs);
925 #elif defined(_MSC_VER) && defined(_M_X64)
931 #else // ABSL_HAVE_INTRINSIC128
940 result += uint128(a32 * b00) << 32;
941 result += uint128(a00 * b32) << 32;
943 #endif // ABSL_HAVE_INTRINSIC128
954 inline uint128 uint128::operator--(
int) {
965 inline uint128& uint128::operator--() {
971 return int128(high, low);
975 inline int128& int128::operator=(
int v) {
976 return *
this = int128(
v);
979 inline int128& int128::operator=(
unsigned int v) {
980 return *
this = int128(
v);
983 inline int128& int128::operator=(
long v) {
984 return *
this = int128(
v);
988 inline int128& int128::operator=(
unsigned long v) {
989 return *
this = int128(
v);
993 inline int128& int128::operator=(
long long v) {
994 return *
this = int128(
v);
998 inline int128& int128::operator=(
unsigned long long v) {
999 return *
this = int128(
v);
1004 int128
operator+(int128 lhs, int128 rhs);
1005 int128
operator-(int128 lhs, int128 rhs);
1006 int128
operator*(int128 lhs, int128 rhs);
1007 int128
operator/(int128 lhs, int128 rhs);
1008 int128
operator%(int128 lhs, int128 rhs);
1009 int128
operator|(int128 lhs, int128 rhs);
1010 int128
operator&(int128 lhs, int128 rhs);
1011 int128
operator^(int128 lhs, int128 rhs);
1016 *
this = *
this + other;
1021 *
this = *
this - other;
1026 *
this = *
this * other;
1031 *
this = *
this / other;
1036 *
this = *
this % other;
1041 *
this = *
this | other;
1046 *
this = *
this & other;
1051 *
this = *
this ^ other;
1055 inline int128& int128::operator<<=(
int amount) {
1056 *
this = *
this << amount;
1060 inline int128& int128::operator>>=(
int amount) {
1061 *
this = *
this >> amount;
1065 namespace int128_internal {
1081 #if defined(ABSL_HAVE_INTRINSIC_INT128)
1082 #include "absl/numeric/int128_have_intrinsic.inc"
1083 #else // ABSL_HAVE_INTRINSIC_INT128
1084 #include "absl/numeric/int128_no_intrinsic.inc"
1085 #endif // ABSL_HAVE_INTRINSIC_INT128
1090 #undef ABSL_INTERNAL_WCHAR_T
1092 #endif // ABSL_NUMERIC_INT128_H_