30template <
bool IS_SIGNED = false>
class Int128 {
37 constexpr Int128(
unsigned n) : low_{n} {}
38 constexpr Int128(
unsigned long n) : low_{n} {}
39 constexpr Int128(
unsigned long long n) : low_{n} {}
40 constexpr Int128(
int n) {
41 low_ =
static_cast<std::uint64_t
>(n);
42 high_ = -
static_cast<std::uint64_t
>(n < 0);
44 constexpr Int128(
long n) {
45 low_ =
static_cast<std::uint64_t
>(n);
46 high_ = -
static_cast<std::uint64_t
>(n < 0);
48 constexpr Int128(
long long n) {
49 low_ =
static_cast<std::uint64_t
>(n);
50 high_ = -
static_cast<std::uint64_t
>(n < 0);
52 constexpr Int128(
const Int128 &) =
default;
53 constexpr Int128(Int128 &&) =
default;
54 constexpr Int128 &operator=(
const Int128 &) =
default;
55 constexpr Int128 &operator=(Int128 &&) =
default;
57 explicit constexpr Int128(
const Int128<!IS_SIGNED> &n)
58 : low_{n.low()}, high_{n.high()} {}
59 explicit constexpr Int128(Int128<!IS_SIGNED> &&n)
60 : low_{n.low()}, high_{n.high()} {}
62 constexpr Int128 operator+()
const {
return *
this; }
63 constexpr Int128 operator~()
const {
return {~high_, ~low_}; }
64 constexpr Int128 operator-()
const {
return ~*
this + 1; }
65 constexpr bool operator!()
const {
return !low_ && !high_; }
66 constexpr explicit operator bool()
const {
return low_ || high_; }
67 constexpr explicit operator std::uint64_t()
const {
return low_; }
68 constexpr explicit operator std::int64_t()
const {
return low_; }
69 constexpr explicit operator int()
const {
return static_cast<int>(low_); }
71 constexpr std::uint64_t high()
const {
return high_; }
72 constexpr std::uint64_t low()
const {
return low_; }
74 constexpr Int128 operator++() {
78 constexpr Int128 operator++(
int ) {
83 constexpr Int128 operator--() {
87 constexpr Int128 operator--(
int ) {
93 constexpr Int128 operator&(Int128 that)
const {
94 return {high_ & that.high_, low_ & that.low_};
96 constexpr Int128 operator|(Int128 that)
const {
97 return {high_ | that.high_, low_ | that.low_};
99 constexpr Int128 operator^(Int128 that)
const {
100 return {high_ ^ that.high_, low_ ^ that.low_};
103 constexpr Int128 operator<<(Int128 that)
const {
106 }
else if (that == 0) {
109 std::uint64_t n{that.low_};
111 return {low_ << (n - 64), 0};
113 return {(high_ << n) | (low_ >> (64 - n)), low_ << n};
117 constexpr Int128 operator>>(Int128 that)
const {
120 }
else if (that == 0) {
123 std::uint64_t n{that.low_};
125 return {0, high_ >> (n - 64)};
127 return {high_ >> n, (high_ << (64 - n)) | (low_ >> n)};
132 constexpr Int128 operator+(Int128 that)
const {
133 std::uint64_t
lower{(low_ & ~topBit) + (that.low_ & ~topBit)};
134 bool carry{((
lower >> 63) + (low_ >> 63) + (that.low_ >> 63)) > 1};
135 return {high_ + that.high_ + carry, low_ + that.low_};
137 constexpr Int128 operator-(Int128 that)
const {
return *
this + -that; }
139 constexpr Int128 operator*(Int128 that)
const {
140 std::uint64_t mask32{0xffffffff};
141 if (high_ == 0 && that.high_ == 0) {
142 std::uint64_t x0{low_ & mask32}, x1{low_ >> 32};
143 std::uint64_t y0{that.low_ & mask32}, y1{that.low_ >> 32};
144 Int128 x0y0{x0 * y0}, x0y1{x0 * y1};
145 Int128 x1y0{x1 * y0}, x1y1{x1 * y1};
146 return x0y0 + ((x0y1 + x1y0) << 32) + (x1y1 << 64);
148 std::uint64_t x0{low_ & mask32}, x1{low_ >> 32}, x2{high_ & mask32},
150 std::uint64_t y0{that.low_ & mask32}, y1{that.low_ >> 32},
151 y2{that.high_ & mask32}, y3{that.high_ >> 32};
152 Int128 x0y0{x0 * y0}, x0y1{x0 * y1}, x0y2{x0 * y2}, x0y3{x0 * y3};
153 Int128 x1y0{x1 * y0}, x1y1{x1 * y1}, x1y2{x1 * y2};
154 Int128 x2y0{x2 * y0}, x2y1{x2 * y1};
155 Int128 x3y0{x3 * y0};
156 return x0y0 + ((x0y1 + x1y0) << 32) + ((x0y2 + x1y1 + x2y0) << 64) +
157 ((x0y3 + x1y2 + x2y1 + x3y0) << 96);
161 constexpr Int128 operator/(Int128 that)
const {
162 int j{LeadingZeroes()};
167 for (; j < 128; ++j) {
169 if (bits.high_ & topBit) {
174 if (numerator >= that) {
182 constexpr Int128 operator%(Int128 that)
const {
183 int j{LeadingZeroes()};
187 for (; j < 128; ++j) {
189 if (bits.high_ & topBit) {
193 if (remainder >= that) {
200 constexpr bool operator<(Int128 that)
const {
201 if (IS_SIGNED && (high_ ^ that.high_) & topBit) {
202 return (high_ & topBit) != 0;
204 return high_ < that.high_ || (high_ == that.high_ && low_ < that.low_);
206 constexpr bool operator<=(Int128 that)
const {
return !(*
this > that); }
207 constexpr bool operator==(Int128 that)
const {
208 return low_ == that.low_ && high_ == that.high_;
210 constexpr bool operator!=(Int128 that)
const {
return !(*
this == that); }
211 constexpr bool operator>=(Int128 that)
const {
return that <= *
this; }
212 constexpr bool operator>(Int128 that)
const {
return that < *
this; }
214 constexpr Int128 &operator&=(
const Int128 &that) {
215 *
this = *
this & that;
218 constexpr Int128 &operator|=(
const Int128 &that) {
219 *
this = *
this | that;
222 constexpr Int128 &operator^=(
const Int128 &that) {
223 *
this = *
this ^ that;
226 constexpr Int128 &operator<<=(
const Int128 &that) {
227 *
this = *
this << that;
230 constexpr Int128 &operator>>=(
const Int128 &that) {
231 *
this = *
this >> that;
234 constexpr Int128 &operator+=(
const Int128 &that) {
235 *
this = *
this + that;
238 constexpr Int128 &operator-=(
const Int128 &that) {
239 *
this = *
this - that;
242 constexpr Int128 &operator*=(
const Int128 &that) {
243 *
this = *
this * that;
246 constexpr Int128 &operator/=(
const Int128 &that) {
247 *
this = *
this / that;
250 constexpr Int128 &operator%=(
const Int128 &that) {
251 *
this = *
this % that;
256 constexpr Int128(std::uint64_t hi, std::uint64_t lo) {
260 constexpr int LeadingZeroes()
const {
262 return 64 + LeadingZeroBitCount(low_);
264 return LeadingZeroBitCount(high_);
268 static constexpr std::uint64_t topBit{std::uint64_t{1} << 63};
270#if FLANG_LITTLE_ENDIAN
271 std::uint64_t low_{0}, high_{0};
272#elif FLANG_BIG_ENDIAN
273 std::uint64_t high_{0}, low_{0};
275#error host endianness is not known