50 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
53 high((x < 0) ? -1 : 0)
59 return low == other.low &&
65 return !(*
this == other);
71 int128_t hi2 = other.high;
73 return hi1 < hi2 || (hi1 == hi2 && low < other.low);
78 return !(other < *
this);
88 return !(*
this < other);
144 res.high = high + other.high;
145 res.low = low + other.low;
147 if (res.low < other.low)
157 res.high = high - other.high;
158 res.low = low - other.low;
171 other.low <= max64 &&
172 ((high == 0 || ~high == 0) &&
173 (other.high == 0 || ~other.high == 0)))
176 (high == other.high) ? 0 : -1);
180 auto al = low & max64;
182 auto bl = other.low & max64;
183 auto bh = other.low >> 64;
192 int256_t(x, w + low * other.high + high * other.low);
198 return div256(other).first;
203 return div256(other).second;
227 return int256_t(0, low << (bits - 128));
229 return int256_t(low << bits, (high << bits) | (low >> (128 - bits)));
235 return int256_t(high >> (bits - 128), 0);
237 return int256_t((low >> bits) | (high << (128 - bits)), high >> bits);
242 *
this = *
this + other;
248 *
this = *
this - other;
254 *
this = *
this * other;
260 *
this = *
this / other;
266 *
this = *
this % other;
272 *
this = *
this & other;
278 *
this = *
this | other;
284 *
this = *
this ^ other;
290 *
this = *
this << bits;
296 *
this = *
this >> bits;
300 template <
typename T,
301 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
307 template <
typename T,
308 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
314 template <
typename T,
315 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
321 template <
typename T,
322 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
328 template <
typename T,
329 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
335 template <
typename T,
336 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
342 template <
typename T,
343 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
349 template <
typename T,
350 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
356 template <
typename T,
357 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
363 template <
typename T,
364 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
370 template <
typename T,
371 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
377 template <
typename T,
378 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
384 template <
typename T,
385 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
391 template <
typename T,
392 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
398 template <
typename T,
399 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
402 return *this << static_cast<std::size_t>(x);
405 template <
typename T,
406 typename =
typename std::enable_if<prt::is_integral<T>::value>::type>
409 return *
this >>
static_cast<std::size_t
>(x);
412 explicit operator std::int8_t()
const
416 :
static_cast<std::int8_t
>(low);
419 explicit operator std::int16_t()
const
423 :
static_cast<std::int16_t
>(low);
426 explicit operator std::int32_t()
const
429 ? -
static_cast<std::int32_t
>(
431 :
static_cast<std::int32_t
>(low);
434 explicit operator std::int64_t()
const
437 ? -
static_cast<std::int64_t
>(
439 :
static_cast<std::int64_t
>(low);
442 explicit operator int128_t()
const
445 ? -
static_cast<int128_t
>(
447 :
static_cast<int128_t
>(low);
450 explicit operator std::uint8_t()
const
452 return static_cast<std::uint8_t
>(low);
455 explicit operator std::uint16_t()
const
457 return static_cast<std::uint16_t
>(low);
460 explicit operator std::uint32_t()
const
462 return static_cast<std::uint32_t
>(low);
465 explicit operator std::uint64_t()
const
467 return static_cast<std::uint64_t
>(low);
470 explicit operator uint128_t()
const
472 return static_cast<uint128_t
>(low);
481 int256_t(uint128_t low, uint128_t high)
498 bool get_bit(std::size_t bit)
const
501 return (high >> (bit - 128)) & 1;
503 return (low >> bit) & 1;
506 void set_bit(std::size_t bit,
bool value)
513 uint128_t mask =
static_cast<uint128_t
>(1) << (bit - 128);
522 uint128_t mask =
static_cast<uint128_t
>(1) << bit;
531 int find_most_significant_bit()
const
546 std::pair<int256_t, int256_t> udiv256(
const int256_t& other)
const
555 return { zero, zero };
559 return { *
this, zero };
561 else if (*
this == other)
563 return { one, zero };
565 else if (*
this == 0 || (*
this != min_value() && *
this < other))
567 return { zero, *
this };
569 else if (high == 0 && other.high == 0)
571 return {
int256_t(low / other.low, 0),
579 for (
int i = find_most_significant_bit(); i >= 0 && i <= 256; i--)
582 remainder.set_bit(
static_cast<std::size_t
>(0), get_bit(
static_cast<std::size_t
>(i)));
584 if (remainder >= other)
587 quotient.set_bit(
static_cast<std::size_t
>(i),
true);
595 std::pair<int256_t, int256_t> div256(
const int256_t& other)
const
603 auto res = x.udiv256(-other);
604 return { res.first, -res.second };
608 auto res = x.udiv256(other);
609 return { -res.first, -res.second };
616 auto res = udiv256(-other);
617 return { -res.first, res.second };
620 return udiv256(other);
637# if defined(__GNUC__)
638# pragma GCC diagnostic push
639# pragma GCC diagnostic ignored "-Wconversion"
641 str +=
'0' + std::int8_t(n % 10);
642# if defined(__GNUC__)
643# pragma GCC diagnostic pop
651 stream << std::string(str.rbegin(), str.rend());
658 std::ostringstream oss;
operator std::int64_t() const
int256_t & operator&=(const int256_t &other)
int256_t operator>>(std::size_t bits) const
int256_t operator+() const
int256_t & operator|=(const int256_t &other)
int256_t & operator^=(const int256_t &other)
bool operator>=(const int256_t &other) const
int256_t operator<<(std::size_t bits) const
bool operator>=(T x) const
bool operator!=(const int256_t &other) const
int256_t & operator-=(const int256_t &other)
int256_t & operator<<=(std::size_t bits)
int256_t operator%(const int256_t &other) const
int256_t operator/(const int256_t &other) const
int256_t & operator%=(const int256_t &other)
bool operator>(const int256_t &other) const
bool operator>(T x) const
int256_t & operator/=(const int256_t &other)
int256_t & operator+=(const int256_t &other)
bool operator<(const int256_t &other) const
int256_t operator+(const int256_t &other) const
int256_t operator^(const int256_t &other) const
int256_t operator-() const
bool operator==(const int256_t &other) const
int256_t operator*(const int256_t &other) const
bool operator<=(T x) const
int256_t operator|(const int256_t &other) const
int256_t operator~() const
bool operator<=(const int256_t &other) const
bool operator==(T x) const
int256_t & operator>>=(std::size_t bits)
int256_t & operator*=(const int256_t &other)
int256_t operator-(const int256_t &other) const
bool operator<(T x) const
bool operator!=(T x) const
int256_t operator&(const int256_t &other) const
Support for int128_t, uint128_t types.
half remainder(half x, half y)
Remainder of division.
std::string to_string(const uint128_t &n)
std::ostream & operator<<(std::ostream &stream, int256_t n)
static constexpr int128_t min()