1#ifndef NEFORCE_CORE_NUMERIC_INT128_HPP__
2#define NEFORCE_CORE_NUMERIC_INT128_HPP__
16NEFORCE_BEGIN_NAMESPACE__
35 NEFORCE_CONSTEXPR20 ~
uint128_t() = default;
41 constexpr uint128_t(const
int32_t low) noexcept :
56 constexpr uint128_t(
const unsigned long low) noexcept :
63 constexpr uint128_t(
const unsigned long long low) noexcept :
80 NEFORCE_NODISCARD constexpr explicit operator
bool() const noexcept {
return lo != 0U || hi != 0U; }
81 NEFORCE_NODISCARD
constexpr explicit operator char() const noexcept {
return static_cast<char>(lo); }
82 NEFORCE_NODISCARD
constexpr explicit operator int8_t() const noexcept {
return static_cast<int8_t>(lo); }
83 NEFORCE_NODISCARD
constexpr explicit operator uint8_t() const noexcept {
return static_cast<uint8_t>(lo); }
84 NEFORCE_NODISCARD
constexpr explicit operator uint16_t() const noexcept {
return static_cast<uint16_t>(lo); }
85 NEFORCE_NODISCARD
constexpr explicit operator uint32_t() const noexcept {
return static_cast<uint32_t>(lo); }
86 NEFORCE_NODISCARD
constexpr explicit operator uint64_t() const noexcept {
return lo; }
87 NEFORCE_NODISCARD
constexpr explicit operator int128_t() const noexcept;
93 NEFORCE_NODISCARD constexpr int128_t to_int128() const noexcept;
100 NEFORCE_NODISCARD constexpr
bool equal_to(const uint128_t& rhs) const noexcept {
101 return hi == rhs.hi &&
lo == rhs.lo;
109 NEFORCE_NODISCARD
constexpr bool less_than(
const uint128_t& rhs)
const noexcept {
110 return hi < rhs.hi || (
hi == rhs.hi &&
lo < rhs.lo);
117 NEFORCE_NODISCARD
constexpr uint128_t
negation() const noexcept {
120 return {new_hi, new_lo};
128 constexpr uint128_t&
operator+=(
const uint128_t& other)
noexcept {
129#if defined(NEFORCE_SUPPORT_INTRINSIC_INT128) && !defined(NEFORCE_PLATFORM_WINDOWS)
130 const auto old_lo =
lo;
145 constexpr uint128_t&
operator-=(
const uint128_t& other)
noexcept {
146#if defined(NEFORCE_SUPPORT_INTRINSIC_INT128) && !defined(NEFORCE_PLATFORM_WINDOWS)
147 const auto old_lo =
lo;
149 hi -= other.hi +
static_cast<uint64_t>(old_lo < other.lo);
184 constexpr uint128_t&
operator++() noexcept {
return *
this += uint128_t{1ULL}; }
190 constexpr uint128_t&
operator--() noexcept {
return *
this -= uint128_t{1ULL}; }
203 constexpr uint128_t&
operator&=(
const uint128_t& other)
noexcept {
214 constexpr uint128_t&
operator|=(
const uint128_t& other)
noexcept {
225 constexpr uint128_t&
operator^=(
const uint128_t& other)
noexcept {
246 hi =
lo << (shift - 64);
250 hi = (
hi << shift) | (
lo >> (64 - shift));
270 lo =
hi >> (shift - 64);
274 lo = (
lo >> shift) | (
hi << (64 - shift));
287#if defined(NEFORCE_SUPPORT_INTRINSIC_INT128) && !defined(NEFORCE_PLATFORM_WINDOWS)
288 const unsigned __int128 prod =
static_cast<unsigned __int128
>(a) * b;
310#if defined(NEFORCE_SUPPORT_INTRINSIC_INT128) && !defined(NEFORCE_PLATFORM_WINDOWS)
311 const unsigned __int128 dividend = (
static_cast<unsigned __int128
>(
hi) << 64) |
lo;
312 const auto quot =
static_cast<uint64_t>(dividend / divisor);
326 NEFORCE_NODISCARD
constexpr size_t to_hash() const noexcept {
327 constexpr uint64_t GOLDEN = 0x9E3779B97F4A7C15ULL;
339 NEFORCE_NODISCARD
static constexpr uint128_t
mul128(
const uint128_t& a,
const uint128_t& b)
noexcept {
341#if defined(NEFORCE_SUPPORT_INTRINSIC_INT128) && !defined(NEFORCE_PLATFORM_WINDOWS)
342 const unsigned __int128 prod = (
static_cast<unsigned __int128
>(a.hi) << 64 | a.lo) *
343 (
static_cast<unsigned __int128
>(b.hi) << 64 | b.lo);
345 result.
hi =
static_cast<uint64_t>(prod >> 64);
355 result.
hi = final_hi;
375 static constexpr uint128_t
min() noexcept {
return {
static_cast<uint64_t>(0),
static_cast<uint64_t>(0)}; }
381 static constexpr uint128_t
max() noexcept {
return {~static_cast<uint64_t>(0), ~static_cast<uint64_t>(0)}; }
392 constexpr int128_t() noexcept = default;
393 NEFORCE_CONSTEXPR20 ~
int128_t() = default;
399 constexpr int128_t(const
long value) noexcept :
407 int128_t(
static_cast<long long>(value)) {}
413 constexpr int128_t(
const long long value) noexcept :
415 hi(value < 0 ? ~
static_cast<uint64_t>(0) : 0) {}
424 hi(negative ? ~static_cast<
uint64_t>(0) : 0) {}
459 NEFORCE_NODISCARD
constexpr explicit operator bool() const noexcept {
return (lo != 0U) || (hi != 0U); }
460 NEFORCE_NODISCARD
constexpr explicit operator char() const noexcept {
return static_cast<char>(lo); }
461 NEFORCE_NODISCARD
constexpr explicit operator int8_t() const noexcept {
return static_cast<int8_t>(lo); }
462 NEFORCE_NODISCARD
constexpr explicit operator int16_t() const noexcept {
return static_cast<int16_t>(lo); }
463 NEFORCE_NODISCARD
constexpr explicit operator int32_t() const noexcept {
return static_cast<int32_t>(lo); }
464 NEFORCE_NODISCARD
constexpr explicit operator int64_t() const noexcept {
return static_cast<int64_t>(lo); }
465 NEFORCE_NODISCARD
constexpr explicit operator uint8_t() const noexcept {
return static_cast<uint8_t>(lo); }
466 NEFORCE_NODISCARD
constexpr explicit operator uint16_t() const noexcept {
return static_cast<uint16_t>(lo); }
467 NEFORCE_NODISCARD
constexpr explicit operator uint32_t() const noexcept {
return static_cast<uint32_t>(lo); }
468 NEFORCE_NODISCARD
constexpr explicit operator uint64_t() const noexcept {
return lo; }
469 NEFORCE_NODISCARD
constexpr explicit operator uint128_t() const noexcept {
return {hi, lo}; }
488 NEFORCE_NODISCARD
constexpr bool equal_to(
const int128_t& rhs)
const noexcept {
489 return hi == rhs.hi &&
lo == rhs.lo;
497 NEFORCE_NODISCARD
constexpr bool less_than(
const int128_t& rhs)
const noexcept {
499 const bool b_neg = rhs.is_negative();
500 if (a_neg != b_neg) {
503 return hi < rhs.hi || (
hi == rhs.hi &&
lo < rhs.lo);
510 NEFORCE_NODISCARD
constexpr int128_t
negation() const noexcept {
513 return {new_hi, new_lo};
521 constexpr int128_t&
operator+=(
const int128_t& other)
noexcept {
535 constexpr int128_t&
operator-=(
const int128_t& other)
noexcept {
549 constexpr int128_t&
operator*=(
const int128_t& other)
noexcept {
578 constexpr int128_t&
operator++() noexcept {
return *
this += int128_t{1}; }
584 constexpr int128_t&
operator--() noexcept {
return *
this -= int128_t{1}; }
590 NEFORCE_NODISCARD
constexpr int128_t
operator~() const noexcept {
return {
~hi,
~lo}; }
597 constexpr int128_t&
operator&=(
const int128_t& other)
noexcept {
608 constexpr int128_t&
operator|=(
const int128_t& other)
noexcept {
619 constexpr int128_t&
operator^=(
const int128_t& other)
noexcept {
646 *
this = neg ? int128_t(~
static_cast<uint64_t>(0), ~
static_cast<uint64_t>(0)) : int128_t(0);
651 hi = neg ? ~0ULL : 0ULL;
653 lo = (
lo >> shift) | (
hi << (64 - shift));
663 NEFORCE_NODISCARD
constexpr size_t to_hash() const noexcept {
664 constexpr uint64_t GOLDEN = 0x9E3779B97F4A7C15ULL;
674 static constexpr int128_t
min() noexcept {
675 return {
static_cast<uint64_t>(0x8000000000000000ULL),
static_cast<uint64_t>(0ULL)};
682 static constexpr int128_t
max() noexcept {
return {0x7FFFFFFFFFFFFFFFULL, ~static_cast<uint64_t>(0)}; }
686 *
this =
mul128(*
this, other);
691 const uint128_t
copy{*
this};
698 const uint128_t
copy{*
this};
709#if defined(NEFORCE_SUPPORT_INTRINSIC_INT128) && !defined(NEFORCE_PLATFORM_WINDOWS)
710 const unsigned __int128 d = (
static_cast<unsigned __int128
>(dividend.
hi) << 64) | dividend.
lo;
711 const unsigned __int128 r = (
static_cast<unsigned __int128
>(divisor.
hi) << 64) | divisor.
lo;
712 const unsigned __int128 q = d / r;
713 const unsigned __int128 m = d % r;
714 quotient = uint128_t{
static_cast<uint64_t>(q >> 64),
static_cast<uint64_t>(q)};
717 if (divisor == uint128_t{1ULL}) {
722 if (dividend < divisor) {
723 quotient = uint128_t{0ULL};
728 const int bits = dividend.
hi != 0 ? (128 -
clz64(dividend.
hi)) : (dividend.
lo != 0 ? (64 -
clz64(dividend.
lo)) : 0);
730 quotient = uint128_t{0ULL};
733 for (
int i = bits - 1; i >= 0; --i) {
735 const uint64_t bit = (i >= 64) ? ((dividend.
hi >> (i - 64)) & 1ULL) : ((dividend.
lo >> i) & 1ULL);
740 quotient.
hi |= (
static_cast<uint64_t>(1) << (i - 64));
742 quotient.
lo |= (
static_cast<uint64_t>(1) << i);
755 const int128_t abs_a = neg_a ?
negation() : *
this;
756 const int128_t abs_b = neg_b ? other.
negation() : other;
758 const int128_t result(q.
hi, q.
lo);
759 *
this = ((neg_a ^ neg_b) != 0) ? result.
negation() : result;
768 const int128_t abs_a = neg_a ?
negation() : *
this;
771 const int128_t result(r.
hi, r.
lo);
772 *
this = neg_a ? result.
negation() : result;
776constexpr uint128_t::operator
int128_t() const noexcept {
return {hi, lo}; }
786struct make_unsigned<int128_t> {
787 using type = uint128_t;
791#define __NEFORCE_DEFINE_MAKE_SIGN(CV) \
793 struct make_signed<uint128_t CV> { \
794 using type = int128_t; \
797 struct make_unsigned<int128_t CV> { \
798 using type = uint128_t; \
801#undef __NEFORCE_DEFINE_MAKE_SIGN
804struct is_integral<uint128_t> :
true_type {};
807struct is_unsigned<uint128_t> :
true_type {};
810struct is_integral<int128_t> :
true_type {};
813struct is_signed<int128_t> :
true_type {};
838 static constexpr bool is_signed =
false;
839 static constexpr bool is_modulo =
true;
841 static constexpr int digits = 128;
842 static constexpr int digits10 = 38;
843 static constexpr int max_digits10 = 0;
844 static constexpr int min_exponent = 0;
845 static constexpr int min_exponent10 = 0;
846 static constexpr int max_exponent = 0;
847 static constexpr int max_exponent10 = 0;
866 static constexpr bool is_signed =
true;
867 static constexpr int digits = 127;
868 static constexpr int digits10 = 38;
869 static constexpr int max_digits10 = 0;
870 static constexpr int min_exponent = 0;
871 static constexpr int min_exponent10 = 0;
872 static constexpr int max_exponent = 0;
873 static constexpr int max_exponent10 = 0;
878NEFORCE_BEGIN_LITERALS__
891NEFORCE_NODISCARD
constexpr uint128_t operator""_u128(
const unsigned long long val)
noexcept {
892 return {
static_cast<uint64_t>(val)};
900NEFORCE_NODISCARD
constexpr int128_t operator""_i128(
const unsigned long long val)
noexcept {
901 return {
static_cast<uint64_t>(val)};
906NEFORCE_END_LITERALS__
907NEFORCE_END_NAMESPACE__
constexpr int clz64(uint64_t x) noexcept
计算64位整数前导零的个数
unsigned char byte_t
字节类型,定义为无符号字符
unsigned int uint32_t
32位无符号整数类型
unsigned long uint64_t
64位无符号整数类型
unsigned char uint8_t
8位无符号整数类型
unsigned short uint16_t
16位无符号整数类型
signed char int8_t
8位有符号整数类型
constexpr int128_t to_int128() const noexcept
转换为有符号128位整数
constexpr uint128_t & operator%=(const uint128_t &other)
取模赋值
constexpr uint128_t & operator*=(const uint128_t &other) noexcept
乘法赋值
constexpr int128_t & operator/=(const int128_t &other)
除法赋值
constexpr uint128_t & operator/=(const uint128_t &other)
除法赋值
constexpr int128_t & operator%=(const int128_t &other)
取模赋值
static constexpr void divmod128(const uint128_t ÷nd, const uint128_t &divisor, uint128_t "ient, uint128_t &remainder)
128位除法辅助函数
constexpr uint8_t _subborrow_u64(const uint8_t borrow_in, const uint64_t a, const uint64_t b, uint64_t *out) noexcept
带借位的64位无符号减法
constexpr uint8_t _addcarry_u64(const uint8_t carry_in, const uint64_t a, const uint64_t b, uint64_t *out) noexcept
带进位的64位无符号加法
constexpr uint64_t _umul128(const uint64_t a, const uint64_t b, uint64_t *hi_out) noexcept
64位无符号乘法
constexpr uint64_t _udiv128(const uint64_t dividend_hi, const uint64_t dividend_lo, const uint64_t divisor, uint64_t *remainder) noexcept
128位无符号除法(基于Knuth-D)
constexpr decimal_t remainder(const decimal_t x, const decimal_t y) noexcept
计算余数
constexpr Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_aux(first, last, result)))
复制范围元素
typename make_integer< Size, IsSigned >::type make_integer_t
make_integer的便捷别名
#define NEFORCE_MACRO_RANGES_CV_REF(MAC)
cv和引用限定符列表宏
bool_constant< true > true_type
表示true的类型
constexpr int128_t & operator-=(const int128_t &other) noexcept
减法赋值
constexpr int128_t(const uint64_t low, const bool negative=false) noexcept
从低64位和符号构造
constexpr int128_t & operator=(const uint128_t &other) noexcept
从无符号128位整数赋值
constexpr size_t to_hash() const noexcept
计算哈希值
constexpr uint128_t to_uint128() const noexcept
转换为无符号128位整数
constexpr int128_t & operator<<=(const uint32_t shift) noexcept
左移赋值
constexpr int128_t & operator+=(const int128_t &other) noexcept
加法赋值
constexpr int128_t & operator--() noexcept
前置自减
constexpr int128_t operator~() const noexcept
按位取反
constexpr int128_t(const uint64_t high, const uint64_t low) noexcept
从高低64位构造
static constexpr int128_t max() noexcept
获取最大值
static constexpr int128_t min() noexcept
获取最小值
constexpr int128_t(const long long value) noexcept
从 long long 构造
constexpr bool equal_to(const int128_t &rhs) const noexcept
相等比较
constexpr int128_t & operator>>=(const uint32_t shift) noexcept
右移赋值(算术右移)
constexpr int128_t & operator^=(const int128_t &other) noexcept
按位异或赋值
constexpr int128_t & operator++() noexcept
前置自增
constexpr bool less_than(const int128_t &rhs) const noexcept
小于比较(考虑符号)
constexpr int128_t & operator*=(const int128_t &other) noexcept
乘法赋值
constexpr int128_t & operator|=(const int128_t &other) noexcept
按位或赋值
constexpr int128_t negation() const noexcept
负号
constexpr bool is_negative() const noexcept
检查是否为负数
constexpr int128_t(const int32_t value) noexcept
从32位有符号整数构造
constexpr int128_t & operator&=(const int128_t &other) noexcept
按位与赋值
constexpr uint128_t(const uint64_t high, const uint64_t low) noexcept
从高低64位构造
static constexpr uint128_t mul64(const uint64_t a, const uint64_t b) noexcept
64位乘法
constexpr bool less_than(const uint128_t &rhs) const noexcept
小于比较
constexpr uint128_t & operator>>=(const uint32_t shift) noexcept
右移赋值
constexpr bool equal_to(const uint128_t &rhs) const noexcept
相等比较
static constexpr uint128_t min() noexcept
获取最小值
constexpr uint128_t & operator--() noexcept
前置自减
constexpr uint128_t & operator|=(const uint128_t &other) noexcept
按位或赋值
constexpr uint128_t & operator<<=(const uint32_t shift) noexcept
左移赋值
constexpr uint128_t & operator^=(const uint128_t &other) noexcept
按位异或赋值
constexpr uint64_t div64(const uint64_t divisor, uint64_t *remainder=nullptr) const
64位除法
constexpr uint128_t & operator+=(const uint128_t &other) noexcept
加法赋值
constexpr uint128_t & operator-=(const uint128_t &other) noexcept
减法赋值
constexpr uint128_t negation() const noexcept
取负
constexpr uint128_t & operator&=(const uint128_t &other) noexcept
按位与赋值
constexpr size_t to_hash() const noexcept
计算哈希值
constexpr uint128_t operator~() const noexcept
按位取反
constexpr uint128_t & operator++() noexcept
前置自增
constexpr uint128_t(const unsigned long long low) noexcept
从无符号 long long 构造
constexpr uint128_t(const unsigned long low) noexcept
从无符号 long 构造
constexpr uint128_t(const uint32_t low) noexcept
从32位无符号整数构造
static constexpr uint128_t max() noexcept
获取最大值
static constexpr uint128_t mul128(const uint128_t &a, const uint128_t &b) noexcept
128位乘法辅助函数