NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
int128.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_NUMERIC_INT128_HPP__
2#define NEFORCE_CORE_NUMERIC_INT128_HPP__
3
10
16NEFORCE_BEGIN_NAMESPACE__
17
23
24struct int128_t;
25
30struct uint128_t : icommon<uint128_t>, iarithmetic<uint128_t>, ibinary<uint128_t> {
33
34 constexpr uint128_t() noexcept = default;
35 NEFORCE_CONSTEXPR20 ~uint128_t() = default;
36
41 constexpr uint128_t(const int32_t low) noexcept :
42 lo(static_cast<uint64_t>(static_cast<int64_t>(low))),
43 hi(low < 0 ? ~static_cast<uint64_t>(0) : 0) {}
44
49 constexpr uint128_t(const uint32_t low) noexcept :
50 lo(low) {}
51
56 constexpr uint128_t(const unsigned long low) noexcept :
57 lo(low) {}
58
63 constexpr uint128_t(const unsigned long long low) noexcept :
64 lo(low) {}
65
71 constexpr uint128_t(const uint64_t high, const uint64_t low) noexcept :
72 lo(low),
73 hi(high) {}
74
75 constexpr uint128_t(const uint128_t&) noexcept = default;
76 constexpr uint128_t& operator=(const uint128_t&) noexcept = default;
77 constexpr uint128_t(uint128_t&&) noexcept = default;
78 constexpr uint128_t& operator=(uint128_t&&) noexcept = default;
79
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;
88
93 NEFORCE_NODISCARD constexpr int128_t to_int128() const noexcept;
94
100 NEFORCE_NODISCARD constexpr bool equal_to(const uint128_t& rhs) const noexcept {
101 return hi == rhs.hi && lo == rhs.lo;
102 }
103
109 NEFORCE_NODISCARD constexpr bool less_than(const uint128_t& rhs) const noexcept {
110 return hi < rhs.hi || (hi == rhs.hi && lo < rhs.lo);
111 }
112
117 NEFORCE_NODISCARD constexpr uint128_t negation() const noexcept {
118 const uint64_t new_lo = ~lo + 1ULL;
119 const uint64_t new_hi = ~hi + (lo == 0ULL ? 1ULL : 0ULL);
120 return {new_hi, new_lo};
121 }
122
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;
131 lo += other.lo;
132 hi += other.hi + static_cast<uint64_t>(lo < old_lo);
133#else
134 const byte_t carry = _NEFORCE _addcarry_u64(0, lo, other.lo, &lo);
135 _NEFORCE _addcarry_u64(carry, hi, other.hi, &hi);
136#endif
137 return *this;
138 }
139
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;
148 lo -= other.lo;
149 hi -= other.hi + static_cast<uint64_t>(old_lo < other.lo);
150#else
151 const byte_t borrow = _NEFORCE _subborrow_u64(0, lo, other.lo, &lo);
152 _NEFORCE _subborrow_u64(borrow, hi, other.hi, &hi);
153#endif
154 return *this;
155 }
156
162 constexpr uint128_t& operator*=(const uint128_t& other) noexcept;
163
170 constexpr uint128_t& operator/=(const uint128_t& other);
171
178 constexpr uint128_t& operator%=(const uint128_t& other);
179
184 constexpr uint128_t& operator++() noexcept { return *this += uint128_t{1ULL}; }
185
190 constexpr uint128_t& operator--() noexcept { return *this -= uint128_t{1ULL}; }
191
196 constexpr uint128_t operator~() const noexcept { return {~hi, ~lo}; }
197
203 constexpr uint128_t& operator&=(const uint128_t& other) noexcept {
204 hi &= other.hi;
205 lo &= other.lo;
206 return *this;
207 }
208
214 constexpr uint128_t& operator|=(const uint128_t& other) noexcept {
215 hi |= other.hi;
216 lo |= other.lo;
217 return *this;
218 }
219
225 constexpr uint128_t& operator^=(const uint128_t& other) noexcept {
226 hi ^= other.hi;
227 lo ^= other.lo;
228 return *this;
229 }
230
236 constexpr uint128_t& operator<<=(const uint32_t shift) noexcept {
237 if (shift == 0) {
238 return *this;
239 }
240 if (shift >= 128) {
241 hi = 0;
242 lo = 0;
243 return *this;
244 }
245 if (shift >= 64) {
246 hi = lo << (shift - 64);
247 lo = 0;
248 return *this;
249 }
250 hi = (hi << shift) | (lo >> (64 - shift));
251 lo = lo << shift;
252 return *this;
253 }
254
260 constexpr uint128_t& operator>>=(const uint32_t shift) noexcept {
261 if (shift == 0) {
262 return *this;
263 }
264 if (shift >= 128) {
265 hi = 0;
266 lo = 0;
267 return *this;
268 }
269 if (shift >= 64) {
270 lo = hi >> (shift - 64);
271 hi = 0;
272 return *this;
273 }
274 lo = (lo >> shift) | (hi << (64 - shift));
275 hi = hi >> shift;
276 return *this;
277 }
278
285 NEFORCE_NODISCARD static constexpr uint128_t mul64(const uint64_t a, const uint64_t b) noexcept {
286 uint128_t res;
287#if defined(NEFORCE_SUPPORT_INTRINSIC_INT128) && !defined(NEFORCE_PLATFORM_WINDOWS)
288 const unsigned __int128 prod = static_cast<unsigned __int128>(a) * b;
289 res.lo = static_cast<uint64_t>(prod);
290 res.hi = static_cast<uint64_t>(prod >> 64);
291#else
292 res.lo = _NEFORCE _umul128(a, b, &res.hi);
293#endif
294 return res;
295 }
296
303 NEFORCE_NODISCARD constexpr uint64_t div64(const uint64_t divisor, uint64_t* remainder = nullptr) const {
304 if (hi == 0) {
305 if (remainder != nullptr) {
306 *remainder = lo % divisor;
307 }
308 return lo / divisor;
309 }
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);
313 if (remainder != nullptr) {
314 *remainder = static_cast<uint64_t>(dividend % divisor);
315 }
316 return quot;
317#else
318 return _NEFORCE _udiv128(hi, lo, divisor, remainder);
319#endif
320 }
321
326 NEFORCE_NODISCARD constexpr size_t to_hash() const noexcept {
327 constexpr uint64_t GOLDEN = 0x9E3779B97F4A7C15ULL;
328 size_t seed = hash<uint64_t>()(lo);
329 seed ^= hash<uint64_t>()(hi) + GOLDEN + (seed << 6) + (seed >> 2);
330 return seed;
331 }
332
339 NEFORCE_NODISCARD static constexpr uint128_t mul128(const uint128_t& a, const uint128_t& b) noexcept {
340 uint128_t result;
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);
344 result.lo = static_cast<uint64_t>(prod);
345 result.hi = static_cast<uint64_t>(prod >> 64);
346#else
347 result.lo = _NEFORCE _umul128(a.lo, b.lo, &result.hi);
348 uint64_t t1_hi = 0, t2_hi = 0;
349 const uint64_t t1_lo = _NEFORCE _umul128(a.lo, b.hi, &t1_hi);
350 const uint64_t t2_lo = _NEFORCE _umul128(a.hi, b.lo, &t2_hi);
351 uint64_t carry_hi = result.hi;
352 const byte_t c1 = _NEFORCE _addcarry_u64(0, carry_hi, t1_lo, &carry_hi);
353 uint64_t final_hi = 0;
354 _NEFORCE _addcarry_u64(c1, carry_hi, t2_lo, &final_hi);
355 result.hi = final_hi;
356#endif
357 return result;
358 }
359
368 constexpr static void divmod128(const uint128_t& dividend, const uint128_t& divisor, uint128_t& quotient,
370
375 static constexpr uint128_t min() noexcept { return {static_cast<uint64_t>(0), static_cast<uint64_t>(0)}; }
376
381 static constexpr uint128_t max() noexcept { return {~static_cast<uint64_t>(0), ~static_cast<uint64_t>(0)}; }
382};
383
388struct int128_t : icommon<int128_t>, iarithmetic<int128_t>, ibinary<int128_t> {
391
392 constexpr int128_t() noexcept = default;
393 NEFORCE_CONSTEXPR20 ~int128_t() = default;
394
399 constexpr int128_t(const long value) noexcept :
400 int128_t(static_cast<make_integer_t<sizeof(long)>>(value)) {}
401
406 constexpr int128_t(const int32_t value) noexcept :
407 int128_t(static_cast<long long>(value)) {}
408
413 constexpr int128_t(const long long value) noexcept :
414 lo(static_cast<uint64_t>(value)),
415 hi(value < 0 ? ~static_cast<uint64_t>(0) : 0) {}
416
422 constexpr int128_t(const uint64_t low, const bool negative = false) noexcept :
423 lo(low),
424 hi(negative ? ~static_cast<uint64_t>(0) : 0) {}
425
431 constexpr int128_t(const uint64_t high, const uint64_t low) noexcept :
432 lo(low),
433 hi(high) {}
434
435 constexpr int128_t(const int128_t&) noexcept = default;
436 constexpr int128_t& operator=(const int128_t&) noexcept = default;
437 constexpr int128_t(int128_t&&) noexcept = default;
438 constexpr int128_t& operator=(int128_t&&) noexcept = default;
439
444 constexpr int128_t(const uint128_t& other) noexcept :
445 lo(other.lo),
446 hi(other.hi) {}
447
453 constexpr int128_t& operator=(const uint128_t& other) noexcept {
454 lo = other.lo;
455 hi = other.hi;
456 return *this;
457 }
458
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}; }
470
475 NEFORCE_NODISCARD constexpr bool is_negative() const noexcept { return static_cast<int64_t>(hi) < 0; }
476
481 NEFORCE_NODISCARD constexpr uint128_t to_uint128() const noexcept { return {hi, lo}; }
482
488 NEFORCE_NODISCARD constexpr bool equal_to(const int128_t& rhs) const noexcept {
489 return hi == rhs.hi && lo == rhs.lo;
490 }
491
497 NEFORCE_NODISCARD constexpr bool less_than(const int128_t& rhs) const noexcept {
498 const bool a_neg = is_negative();
499 const bool b_neg = rhs.is_negative();
500 if (a_neg != b_neg) {
501 return a_neg;
502 }
503 return hi < rhs.hi || (hi == rhs.hi && lo < rhs.lo);
504 }
505
510 NEFORCE_NODISCARD constexpr int128_t negation() const noexcept {
511 const uint64_t new_lo = ~lo + 1ULL;
512 const uint64_t new_hi = ~hi + (lo == 0ULL ? 1ULL : 0ULL);
513 return {new_hi, new_lo};
514 }
515
521 constexpr int128_t& operator+=(const int128_t& other) noexcept {
522 const uint128_t a = to_uint128();
523 const uint128_t b = other.to_uint128();
524 const uint128_t c = a + b;
525 lo = c.lo;
526 hi = c.hi;
527 return *this;
528 }
529
535 constexpr int128_t& operator-=(const int128_t& other) noexcept {
536 const uint128_t a = to_uint128();
537 const uint128_t b = other.to_uint128();
538 const uint128_t c = a - b;
539 lo = c.lo;
540 hi = c.hi;
541 return *this;
542 }
543
549 constexpr int128_t& operator*=(const int128_t& other) noexcept {
550 const uint128_t a = to_uint128();
551 const uint128_t b = other.to_uint128();
552 const uint128_t c = a * b;
553 lo = c.lo;
554 hi = c.hi;
555 return *this;
556 }
557
564 constexpr int128_t& operator/=(const int128_t& other);
565
572 constexpr int128_t& operator%=(const int128_t& other);
573
578 constexpr int128_t& operator++() noexcept { return *this += int128_t{1}; }
579
584 constexpr int128_t& operator--() noexcept { return *this -= int128_t{1}; }
585
590 NEFORCE_NODISCARD constexpr int128_t operator~() const noexcept { return {~hi, ~lo}; }
591
597 constexpr int128_t& operator&=(const int128_t& other) noexcept {
598 hi &= other.hi;
599 lo &= other.lo;
600 return *this;
601 }
602
608 constexpr int128_t& operator|=(const int128_t& other) noexcept {
609 hi |= other.hi;
610 lo |= other.lo;
611 return *this;
612 }
613
619 constexpr int128_t& operator^=(const int128_t& other) noexcept {
620 hi ^= other.hi;
621 lo ^= other.lo;
622 return *this;
623 }
624
630 constexpr int128_t& operator<<=(const uint32_t shift) noexcept {
631 *this = to_uint128() << shift;
632 return *this;
633 }
634
640 constexpr int128_t& operator>>=(const uint32_t shift) noexcept {
641 if (shift == 0) {
642 return *this;
643 }
644 const bool neg = is_negative();
645 if (shift >= 128) {
646 *this = neg ? int128_t(~static_cast<uint64_t>(0), ~static_cast<uint64_t>(0)) : int128_t(0);
647 return *this;
648 }
649 if (shift >= 64) {
650 lo = static_cast<uint64_t>(static_cast<int64_t>(hi) >> (shift - 64));
651 hi = neg ? ~0ULL : 0ULL;
652 } else {
653 lo = (lo >> shift) | (hi << (64 - shift));
654 hi = static_cast<uint64_t>(static_cast<int64_t>(hi) >> shift);
655 }
656 return *this;
657 }
658
663 NEFORCE_NODISCARD constexpr size_t to_hash() const noexcept {
664 constexpr uint64_t GOLDEN = 0x9E3779B97F4A7C15ULL;
665 size_t seed = hash<uint64_t>()(lo);
666 seed ^= hash<uint64_t>()(hi) + GOLDEN + (seed << 6) + (seed >> 2);
667 return seed;
668 }
669
674 static constexpr int128_t min() noexcept {
675 return {static_cast<uint64_t>(0x8000000000000000ULL), static_cast<uint64_t>(0ULL)};
676 }
677
682 static constexpr int128_t max() noexcept { return {0x7FFFFFFFFFFFFFFFULL, ~static_cast<uint64_t>(0)}; }
683};
684
685constexpr uint128_t& uint128_t::operator*=(const uint128_t& other) noexcept {
686 *this = mul128(*this, other);
687 return *this;
688}
689
690constexpr uint128_t& uint128_t::operator/=(const uint128_t& other) {
691 const uint128_t copy{*this};
692 uint128_t r;
693 divmod128(copy, other, *this, r);
694 return *this;
695}
696
697constexpr uint128_t& uint128_t::operator%=(const uint128_t& other) {
698 const uint128_t copy{*this};
699 uint128_t q;
700 divmod128(copy, other, q, *this);
701 return *this;
702}
703
704constexpr void uint128_t::divmod128(const uint128_t& dividend, const uint128_t& divisor, uint128_t& quotient,
705 uint128_t& remainder) {
706 if (!divisor) {
707 NEFORCE_THROW_EXCEPTION(math_exception("Division by zero"));
708 }
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)};
715 remainder = uint128_t{static_cast<uint64_t>(m >> 64), static_cast<uint64_t>(m)};
716#else
717 if (divisor == uint128_t{1ULL}) {
718 quotient = dividend;
719 remainder = uint128_t{0ULL};
720 return;
721 }
722 if (dividend < divisor) {
723 quotient = uint128_t{0ULL};
724 remainder = dividend;
725 return;
726 }
727
728 const int bits = dividend.hi != 0 ? (128 - clz64(dividend.hi)) : (dividend.lo != 0 ? (64 - clz64(dividend.lo)) : 0);
729
730 quotient = uint128_t{0ULL};
731 remainder = uint128_t{0ULL};
732
733 for (int i = bits - 1; i >= 0; --i) {
734 remainder <<= 1;
735 const uint64_t bit = (i >= 64) ? ((dividend.hi >> (i - 64)) & 1ULL) : ((dividend.lo >> i) & 1ULL);
736 remainder.lo |= bit;
737 if (remainder >= divisor) {
738 remainder -= divisor;
739 if (i >= 64) {
740 quotient.hi |= (static_cast<uint64_t>(1) << (i - 64));
741 } else {
742 quotient.lo |= (static_cast<uint64_t>(1) << i);
743 }
744 }
745 }
746#endif
747}
748
749constexpr int128_t& int128_t::operator/=(const int128_t& other) {
750 if (!other) {
751 NEFORCE_THROW_EXCEPTION(math_exception("Division by zero"));
752 }
753 const bool neg_a = is_negative();
754 const bool neg_b = other.is_negative();
755 const int128_t abs_a = neg_a ? negation() : *this;
756 const int128_t abs_b = neg_b ? other.negation() : other;
757 const uint128_t q = abs_a.to_uint128() / abs_b.to_uint128();
758 const int128_t result(q.hi, q.lo);
759 *this = ((neg_a ^ neg_b) != 0) ? result.negation() : result;
760 return *this;
761}
762
763constexpr int128_t& int128_t::operator%=(const int128_t& other) {
764 if (!other) {
765 NEFORCE_THROW_EXCEPTION(math_exception("Division by zero"));
766 }
767 const bool neg_a = is_negative();
768 const int128_t abs_a = neg_a ? negation() : *this;
769 const int128_t abs_b = other.is_negative() ? other.negation() : other;
770 const uint128_t r = abs_a.to_uint128() % abs_b.to_uint128();
771 const int128_t result(r.hi, r.lo);
772 *this = neg_a ? result.negation() : result;
773 return *this;
774}
775
776constexpr uint128_t::operator int128_t() const noexcept { return {hi, lo}; }
777constexpr int128_t uint128_t::to_int128() const noexcept { return {hi, lo}; }
778
779
780template <>
781struct make_signed<uint128_t> {
782 using type = int128_t;
783};
784
785template <>
786struct make_unsigned<int128_t> {
787 using type = uint128_t;
788};
789
790
791#define __NEFORCE_DEFINE_MAKE_SIGN(CV) \
792 template <> \
793 struct make_signed<uint128_t CV> { \
794 using type = int128_t; \
795 }; \
796 template <> \
797 struct make_unsigned<int128_t CV> { \
798 using type = uint128_t; \
799 };
800NEFORCE_MACRO_RANGES_CV_REF(__NEFORCE_DEFINE_MAKE_SIGN)
801#undef __NEFORCE_DEFINE_MAKE_SIGN
802
803template <>
804struct is_integral<uint128_t> : true_type {};
805
806template <>
807struct is_unsigned<uint128_t> : true_type {};
808
809template <>
810struct is_integral<int128_t> : true_type {};
811
812template <>
813struct is_signed<int128_t> : true_type {};
814 // Int128
816
821
825template <>
826class numeric_traits<uint128_t> : public inner::numeric_int_base {
827public:
828 static constexpr uint128_t min() noexcept { return uint128_t::min(); }
829 static constexpr uint128_t lowest() noexcept { return uint128_t::min(); }
830 static constexpr uint128_t max() noexcept { return uint128_t::max(); }
831 static constexpr uint128_t epsilon() noexcept { return uint128_t{0ULL}; }
832 static constexpr uint128_t round_error() noexcept { return uint128_t{0ULL}; }
833 static constexpr uint128_t infinity() noexcept { return uint128_t{0ULL}; }
834 static constexpr uint128_t quiet_nan() noexcept { return uint128_t{0ULL}; }
835 static constexpr uint128_t signaling_nan() noexcept { return uint128_t{0ULL}; }
836 static constexpr uint128_t denorm_min() noexcept { return uint128_t{0ULL}; }
837
838 static constexpr bool is_signed = false;
839 static constexpr bool is_modulo = true;
840
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;
848};
849
853template <>
854class numeric_traits<int128_t> : public inner::numeric_int_base {
855public:
856 static constexpr int128_t min() noexcept { return int128_t::min(); }
857 static constexpr int128_t lowest() noexcept { return int128_t::min(); }
858 static constexpr int128_t max() noexcept { return int128_t::max(); }
859 static constexpr int128_t epsilon() noexcept { return int128_t{0}; }
860 static constexpr int128_t round_error() noexcept { return int128_t{0}; }
861 static constexpr int128_t infinity() noexcept { return int128_t{0}; }
862 static constexpr int128_t quiet_nan() noexcept { return int128_t{0}; }
863 static constexpr int128_t signaling_nan() noexcept { return int128_t{0}; }
864 static constexpr int128_t denorm_min() noexcept { return int128_t{0}; }
865
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;
874};
875 // NumericTraits
877
878NEFORCE_BEGIN_LITERALS__
879
885
891NEFORCE_NODISCARD constexpr uint128_t operator""_u128(const unsigned long long val) noexcept {
892 return {static_cast<uint64_t>(val)};
893}
894
900NEFORCE_NODISCARD constexpr int128_t operator""_i128(const unsigned long long val) noexcept {
901 return {static_cast<uint64_t>(val)};
902}
903 // UserLiterals
905
906NEFORCE_END_LITERALS__
907NEFORCE_END_NAMESPACE__
908#endif // NEFORCE_CORE_NUMERIC_INT128_HPP__
数值类型极限特性主模板
异常处理框架
constexpr int clz64(uint64_t x) noexcept
计算64位整数前导零的个数
定义 bit.hpp:40
long int64_t
64位有符号整数类型
unsigned char byte_t
字节类型,定义为无符号字符
unsigned int uint32_t
32位无符号整数类型
unsigned long uint64_t
64位无符号整数类型
unsigned char uint8_t
8位无符号整数类型
int int32_t
32位有符号整数类型
unsigned short uint16_t
16位无符号整数类型
short int16_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 &dividend, const uint128_t &divisor, uint128_t &quotient, 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的类型
基本接口基类
数值操作接口
MSVC内部函数替代实现
数值特征
哈希函数的主模板
算术运算接口基类
位运算接口基类
通用接口,同时具备可比较和可哈希功能
128位有符号整数类型
uint64_t hi
高64位
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
获取最大值
uint64_t lo
低64位
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
按位与赋值
将类整数类型转换为对应的有符号类型
128位无符号整数类型
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
相等比较
uint64_t lo
低64位
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
加法赋值
uint64_t hi
高64位
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位乘法辅助函数