Changes imported from Abseil "staging" branch:
- b7ac57541b07fadc3ed054cc3d62bc192a2098a7 Redefine arithmetic assign operators in terms of the bina... by Alex Strelnikov <strel@google.com> - bb2bf3fd86eb9f24420376aad1b9fe84068ad7e4 Cmake CI for Ubuntu by Jon Cohen <cohenjon@google.com> - 3ff3e6d6b4d99627f0785cad5b562362bdf1ae37 Fix internal namespace (debug_internal -> debugging_inter... by Derek Mauro <dmauro@google.com> - b50753d757c95a3430cc2d6cfc0272af1e5c219c Internal change. by Alex Strelnikov <strel@google.com> GitOrigin-RevId: b7ac57541b07fadc3ed054cc3d62bc192a2098a7 Change-Id: I7561639e296d1cc5dc7ee75e6645e8dae3f1bf97
This commit is contained in:
parent
bf7fc9986e
commit
3917120a4c
12 changed files with 116 additions and 86 deletions
|
|
@ -20,6 +20,7 @@
|
|||
#include <iostream> // NOLINT(readability/streams)
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace absl {
|
||||
|
||||
|
|
@ -128,19 +129,17 @@ uint128::uint128(float v) : uint128(MakeUint128FromFloat(v)) {}
|
|||
uint128::uint128(double v) : uint128(MakeUint128FromFloat(v)) {}
|
||||
uint128::uint128(long double v) : uint128(MakeUint128FromFloat(v)) {}
|
||||
|
||||
uint128& uint128::operator/=(uint128 other) {
|
||||
uint128 operator/(uint128 lhs, uint128 rhs) {
|
||||
uint128 quotient = 0;
|
||||
uint128 remainder = 0;
|
||||
DivModImpl(*this, other, "ient, &remainder);
|
||||
*this = quotient;
|
||||
return *this;
|
||||
DivModImpl(lhs, rhs, "ient, &remainder);
|
||||
return quotient;
|
||||
}
|
||||
uint128& uint128::operator%=(uint128 other) {
|
||||
uint128 operator%(uint128 lhs, uint128 rhs) {
|
||||
uint128 quotient = 0;
|
||||
uint128 remainder = 0;
|
||||
DivModImpl(*this, other, "ient, &remainder);
|
||||
*this = remainder;
|
||||
return *this;
|
||||
DivModImpl(lhs, rhs, "ient, &remainder);
|
||||
return remainder;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
|||
|
|
@ -262,21 +262,50 @@ inline uint128& uint128::operator=(unsigned __int128 v) {
|
|||
}
|
||||
#endif // ABSL_HAVE_INTRINSIC_INT128
|
||||
|
||||
// Shift and arithmetic operators.
|
||||
// Arithmetic operators.
|
||||
|
||||
inline uint128 operator<<(uint128 lhs, int amount) { return lhs <<= amount; }
|
||||
uint128 operator<<(uint128 lhs, int amount);
|
||||
uint128 operator>>(uint128 lhs, int amount);
|
||||
uint128 operator+(uint128 lhs, uint128 rhs);
|
||||
uint128 operator-(uint128 lhs, uint128 rhs);
|
||||
uint128 operator*(uint128 lhs, uint128 rhs);
|
||||
uint128 operator/(uint128 lhs, uint128 rhs);
|
||||
uint128 operator%(uint128 lhs, uint128 rhs);
|
||||
|
||||
inline uint128 operator>>(uint128 lhs, int amount) { return lhs >>= amount; }
|
||||
inline uint128& uint128::operator<<=(int amount) {
|
||||
*this = *this << amount;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128 operator+(uint128 lhs, uint128 rhs) { return lhs += rhs; }
|
||||
inline uint128& uint128::operator>>=(int amount) {
|
||||
*this = *this >> amount;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128 operator-(uint128 lhs, uint128 rhs) { return lhs -= rhs; }
|
||||
inline uint128& uint128::operator+=(uint128 other) {
|
||||
*this = *this + other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128 operator*(uint128 lhs, uint128 rhs) { return lhs *= rhs; }
|
||||
inline uint128& uint128::operator-=(uint128 other) {
|
||||
*this = *this - other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128 operator/(uint128 lhs, uint128 rhs) { return lhs /= rhs; }
|
||||
inline uint128& uint128::operator*=(uint128 other) {
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128 operator%(uint128 lhs, uint128 rhs) { return lhs %= rhs; }
|
||||
inline uint128& uint128::operator/=(uint128 other) {
|
||||
*this = *this / other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator%=(uint128 other) {
|
||||
*this = *this % other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr uint64_t Uint128Low64(uint128 v) { return v.lo_; }
|
||||
|
||||
|
|
@ -514,9 +543,9 @@ inline uint128& uint128::operator^=(uint128 other) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
// Shift and arithmetic assign operators.
|
||||
// Arithmetic operators.
|
||||
|
||||
inline uint128& uint128::operator<<=(int amount) {
|
||||
inline uint128 operator<<(uint128 lhs, int amount) {
|
||||
assert(amount >= 0); // Negative shifts are undefined.
|
||||
assert(amount < 128); // Shifts of >= 128 are undefined.
|
||||
|
||||
|
|
@ -524,17 +553,16 @@ inline uint128& uint128::operator<<=(int amount) {
|
|||
// special-casing.
|
||||
if (amount < 64) {
|
||||
if (amount != 0) {
|
||||
hi_ = (hi_ << amount) | (lo_ >> (64 - amount));
|
||||
lo_ = lo_ << amount;
|
||||
return MakeUint128(
|
||||
(Uint128High64(lhs) << amount) | (Uint128Low64(lhs) >> (64 - amount)),
|
||||
Uint128Low64(lhs) << amount);
|
||||
}
|
||||
} else {
|
||||
hi_ = lo_ << (amount - 64);
|
||||
lo_ = 0;
|
||||
return lhs;
|
||||
}
|
||||
return *this;
|
||||
return MakeUint128(Uint128Low64(lhs) << (amount - 64), 0);
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator>>=(int amount) {
|
||||
inline uint128 operator>>(uint128 lhs, int amount) {
|
||||
assert(amount >= 0); // Negative shifts are undefined.
|
||||
assert(amount < 128); // Shifts of >= 128 are undefined.
|
||||
|
||||
|
|
@ -542,49 +570,51 @@ inline uint128& uint128::operator>>=(int amount) {
|
|||
// special-casing.
|
||||
if (amount < 64) {
|
||||
if (amount != 0) {
|
||||
lo_ = (lo_ >> amount) | (hi_ << (64 - amount));
|
||||
hi_ = hi_ >> amount;
|
||||
return MakeUint128(Uint128High64(lhs) >> amount,
|
||||
(Uint128Low64(lhs) >> amount) |
|
||||
(Uint128High64(lhs) << (64 - amount)));
|
||||
}
|
||||
} else {
|
||||
lo_ = hi_ >> (amount - 64);
|
||||
hi_ = 0;
|
||||
return lhs;
|
||||
}
|
||||
return *this;
|
||||
return MakeUint128(0, Uint128High64(lhs) >> (amount - 64));
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator+=(uint128 other) {
|
||||
hi_ += other.hi_;
|
||||
uint64_t lolo = lo_ + other.lo_;
|
||||
if (lolo < lo_)
|
||||
++hi_;
|
||||
lo_ = lolo;
|
||||
return *this;
|
||||
inline uint128 operator+(uint128 lhs, uint128 rhs) {
|
||||
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;
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator-=(uint128 other) {
|
||||
hi_ -= other.hi_;
|
||||
if (other.lo_ > lo_) --hi_;
|
||||
lo_ -= other.lo_;
|
||||
return *this;
|
||||
inline uint128 operator-(uint128 lhs, uint128 rhs) {
|
||||
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;
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator*=(uint128 other) {
|
||||
inline uint128 operator*(uint128 lhs, uint128 rhs) {
|
||||
#if defined(ABSL_HAVE_INTRINSIC_INT128)
|
||||
// TODO(strel) Remove once alignment issues are resolved and unsigned __int128
|
||||
// can be used for uint128 storage.
|
||||
*this = static_cast<unsigned __int128>(*this) *
|
||||
static_cast<unsigned __int128>(other);
|
||||
return *this;
|
||||
return static_cast<unsigned __int128>(lhs) *
|
||||
static_cast<unsigned __int128>(rhs);
|
||||
#else // ABSL_HAVE_INTRINSIC128
|
||||
uint64_t a32 = lo_ >> 32;
|
||||
uint64_t a00 = lo_ & 0xffffffff;
|
||||
uint64_t b32 = other.lo_ >> 32;
|
||||
uint64_t b00 = other.lo_ & 0xffffffff;
|
||||
hi_ = hi_ * other.lo_ + lo_ * other.hi_ + a32 * b32;
|
||||
lo_ = a00 * b00;
|
||||
*this += uint128(a32 * b00) << 32;
|
||||
*this += uint128(a00 * b32) << 32;
|
||||
return *this;
|
||||
uint64_t a32 = Uint128Low64(lhs) >> 32;
|
||||
uint64_t a00 = Uint128Low64(lhs) & 0xffffffff;
|
||||
uint64_t b32 = Uint128Low64(rhs) >> 32;
|
||||
uint64_t b00 = Uint128Low64(rhs) & 0xffffffff;
|
||||
uint128 result =
|
||||
MakeUint128(Uint128High64(lhs) * Uint128Low64(rhs) +
|
||||
Uint128Low64(lhs) * Uint128High64(rhs) + a32 * b32,
|
||||
a00 * b00);
|
||||
result += uint128(a32 * b00) << 32;
|
||||
result += uint128(a00 * b32) << 32;
|
||||
return result;
|
||||
#endif // ABSL_HAVE_INTRINSIC128
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue