diff options
Diffstat (limited to 'absl/numeric')
-rw-r--r-- | absl/numeric/int128.cc | 13 | ||||
-rw-r--r-- | absl/numeric/int128.h | 73 |
2 files changed, 67 insertions, 19 deletions
diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc index 5160df79..17d88744 100644 --- a/absl/numeric/int128.cc +++ b/absl/numeric/int128.cc @@ -138,28 +138,21 @@ uint128::uint128(float v) : uint128(MakeUint128FromFloat(v)) {} uint128::uint128(double v) : uint128(MakeUint128FromFloat(v)) {} uint128::uint128(long double v) : uint128(MakeUint128FromFloat(v)) {} +#if !defined(ABSL_HAVE_INTRINSIC_INT128) uint128 operator/(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) / - static_cast<unsigned __int128>(rhs); -#else // ABSL_HAVE_INTRINSIC_INT128 uint128 quotient = 0; uint128 remainder = 0; DivModImpl(lhs, rhs, "ient, &remainder); return quotient; -#endif // ABSL_HAVE_INTRINSIC_INT128 } + uint128 operator%(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) % - static_cast<unsigned __int128>(rhs); -#else // ABSL_HAVE_INTRINSIC_INT128 uint128 quotient = 0; uint128 remainder = 0; DivModImpl(lhs, rhs, "ient, &remainder); return remainder; -#endif // ABSL_HAVE_INTRINSIC_INT128 } +#endif // !defined(ABSL_HAVE_INTRINSIC_INT128) namespace { diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 198aa195..a9cbe489 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h @@ -18,6 +18,10 @@ // ----------------------------------------------------------------------------- // // This header file defines 128-bit integer types, `uint128` and `int128`. +// +// TODO(absl-team): This module is inconsistent as many inline `uint128` methods +// are defined in this file, while many inline `int128` methods are defined in +// the `int128_*_intrinsic.inc` files. #ifndef ABSL_NUMERIC_INT128_H_ #define ABSL_NUMERIC_INT128_H_ @@ -783,8 +787,13 @@ inline uint128::operator long double() const { // Comparison operators. inline bool operator==(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) == + static_cast<unsigned __int128>(rhs); +#else return (Uint128Low64(lhs) == Uint128Low64(rhs) && Uint128High64(lhs) == Uint128High64(rhs)); +#endif } inline bool operator!=(uint128 lhs, uint128 rhs) { @@ -819,52 +828,76 @@ constexpr inline int128 operator+(int128 val) { } inline uint128 operator-(uint128 val) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return -static_cast<unsigned __int128>(val); +#else uint64_t hi = ~Uint128High64(val); uint64_t lo = ~Uint128Low64(val) + 1; if (lo == 0) ++hi; // carry return MakeUint128(hi, lo); +#endif } constexpr inline bool operator!(uint128 val) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return !static_cast<unsigned __int128>(val); +#else return !Uint128High64(val) && !Uint128Low64(val); +#endif } // Logical operators. constexpr inline uint128 operator~(uint128 val) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return ~static_cast<unsigned __int128>(val); +#else return MakeUint128(~Uint128High64(val), ~Uint128Low64(val)); +#endif } constexpr inline uint128 operator|(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) | + static_cast<unsigned __int128>(rhs); +#else return MakeUint128(Uint128High64(lhs) | Uint128High64(rhs), - Uint128Low64(lhs) | Uint128Low64(rhs)); + Uint128Low64(lhs) | Uint128Low64(rhs)); +#endif } constexpr inline uint128 operator&(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) & + static_cast<unsigned __int128>(rhs); +#else return MakeUint128(Uint128High64(lhs) & Uint128High64(rhs), - Uint128Low64(lhs) & Uint128Low64(rhs)); + Uint128Low64(lhs) & Uint128Low64(rhs)); +#endif } constexpr inline uint128 operator^(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) ^ + static_cast<unsigned __int128>(rhs); +#else return MakeUint128(Uint128High64(lhs) ^ Uint128High64(rhs), - Uint128Low64(lhs) ^ Uint128Low64(rhs)); + Uint128Low64(lhs) ^ Uint128Low64(rhs)); +#endif } inline uint128& uint128::operator|=(uint128 other) { - hi_ |= other.hi_; - lo_ |= other.lo_; + *this = *this | other; return *this; } inline uint128& uint128::operator&=(uint128 other) { - hi_ &= other.hi_; - lo_ &= other.lo_; + *this = *this & other; return *this; } inline uint128& uint128::operator^=(uint128 other) { - hi_ ^= other.hi_; - lo_ ^= other.lo_; + *this = *this ^ other; return *this; } @@ -907,21 +940,31 @@ inline uint128 operator>>(uint128 lhs, int amount) { } inline uint128 operator+(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) + + static_cast<unsigned __int128>(rhs); +#else uint128 result = MakeUint128(Uint128High64(lhs) + Uint128High64(rhs), Uint128Low64(lhs) + Uint128Low64(rhs)); if (Uint128Low64(result) < Uint128Low64(lhs)) { // check for carry return MakeUint128(Uint128High64(result) + 1, Uint128Low64(result)); } return result; +#endif } inline uint128 operator-(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) - + static_cast<unsigned __int128>(rhs); +#else uint128 result = MakeUint128(Uint128High64(lhs) - Uint128High64(rhs), Uint128Low64(lhs) - Uint128Low64(rhs)); if (Uint128Low64(lhs) < Uint128Low64(rhs)) { // check for carry return MakeUint128(Uint128High64(result) - 1, Uint128Low64(result)); } return result; +#endif } inline uint128 operator*(uint128 lhs, uint128 rhs) { @@ -951,6 +994,18 @@ inline uint128 operator*(uint128 lhs, uint128 rhs) { #endif // ABSL_HAVE_INTRINSIC128 } +#if defined(ABSL_HAVE_INTRINSIC_INT128) +inline uint128 operator/(uint128 lhs, uint128 rhs) { + return static_cast<unsigned __int128>(lhs) / + static_cast<unsigned __int128>(rhs); +} + +inline uint128 operator%(uint128 lhs, uint128 rhs) { + return static_cast<unsigned __int128>(lhs) % + static_cast<unsigned __int128>(rhs); +} +#endif + // Increment/decrement operators. inline uint128 uint128::operator++(int) { |