From 24cce06f80fbf1769d6637ee413bee884226f4ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 5 May 2022 09:42:00 +0200 Subject: [PATCH 1/4] Simplify conversions for operator+ --- include/intx/intx.hpp | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/include/intx/intx.hpp b/include/intx/intx.hpp index aebf1f93..efd02f13 100644 --- a/include/intx/intx.hpp +++ b/include/intx/intx.hpp @@ -1068,6 +1068,13 @@ struct uint static_assert(sizeof(Int) <= sizeof(uint64_t)); return static_cast(words_[0]); } + + friend inline constexpr uint operator+(const uint& x, const uint& y) noexcept + { + return addc(x, y).value; + } + + inline constexpr uint& operator+=(const uint& y) noexcept { return *this = *this + y; } }; using uint192 = uint<192>; @@ -1458,12 +1465,6 @@ inline const uint8_t* as_bytes(const T& x) noexcept return reinterpret_cast(&x); } -template -inline constexpr uint operator+(const uint& x, const uint& y) noexcept -{ - return addc(x, y).value; -} - template inline constexpr uint operator-(const uint& x) noexcept { @@ -1476,13 +1477,6 @@ inline constexpr uint operator-(const uint& x, const uint& y) noexcept return subc(x, y).value; } -template >::value>::type> -inline constexpr uint& operator+=(uint& x, const T& y) noexcept -{ - return x = x + y; -} - template >::value>::type> inline constexpr uint& operator-=(uint& x, const T& y) noexcept @@ -1878,20 +1872,6 @@ inline constexpr uint bswap(const uint& x) noexcept // Support for type conversions for binary operators. -template >::value>::type> -inline constexpr uint operator+(const uint& x, const T& y) noexcept -{ - return x + uint(y); -} - -template >::value>::type> -inline constexpr uint operator+(const T& x, const uint& y) noexcept -{ - return uint(x) + y; -} - template >::value>::type> inline constexpr uint operator-(const uint& x, const T& y) noexcept From efe920e7c4030e5ac4ac02633e5d11b4ad6952cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 16 May 2022 21:00:11 +0200 Subject: [PATCH 2/4] Simplify conversions for operator- --- include/intx/intx.hpp | 42 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/include/intx/intx.hpp b/include/intx/intx.hpp index efd02f13..1a394fc3 100644 --- a/include/intx/intx.hpp +++ b/include/intx/intx.hpp @@ -1075,6 +1075,15 @@ struct uint } inline constexpr uint& operator+=(const uint& y) noexcept { return *this = *this + y; } + + inline constexpr uint operator-() const noexcept { return ~*this + uint{1}; } + + friend inline constexpr uint operator-(const uint& x, const uint& y) noexcept + { + return subc(x, y).value; + } + + inline constexpr uint& operator-=(const uint& y) noexcept { return *this = *this - y; } }; using uint192 = uint<192>; @@ -1465,25 +1474,6 @@ inline const uint8_t* as_bytes(const T& x) noexcept return reinterpret_cast(&x); } -template -inline constexpr uint operator-(const uint& x) noexcept -{ - return ~x + uint{1}; -} - -template -inline constexpr uint operator-(const uint& x, const uint& y) noexcept -{ - return subc(x, y).value; -} - -template >::value>::type> -inline constexpr uint& operator-=(uint& x, const T& y) noexcept -{ - return x = x - y; -} - template inline constexpr uint<2 * N> umul(const uint& x, const uint& y) noexcept { @@ -1872,20 +1862,6 @@ inline constexpr uint bswap(const uint& x) noexcept // Support for type conversions for binary operators. -template >::value>::type> -inline constexpr uint operator-(const uint& x, const T& y) noexcept -{ - return x - uint(y); -} - -template >::value>::type> -inline constexpr uint operator-(const T& x, const uint& y) noexcept -{ - return uint(x) - y; -} - template >::value>::type> inline constexpr uint operator*(const uint& x, const T& y) noexcept From bc88cb8cade088446c7de4fcef0633ca721b237c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 16 May 2022 22:11:02 +0200 Subject: [PATCH 3/4] Simplify conversions for operator* --- include/intx/intx.hpp | 66 +++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 44 deletions(-) diff --git a/include/intx/intx.hpp b/include/intx/intx.hpp index 1a394fc3..df6e492a 100644 --- a/include/intx/intx.hpp +++ b/include/intx/intx.hpp @@ -1084,6 +1084,28 @@ struct uint } inline constexpr uint& operator-=(const uint& y) noexcept { return *this = *this - y; } + + /// Multiplication implementation using word access + /// and discarding the high part of the result product. + friend inline constexpr uint operator*(const uint& x, const uint& y) noexcept + { + uint p; + for (size_t j = 0; j < num_words; j++) + { + uint64_t k = 0; + for (size_t i = 0; i < (num_words - j - 1); i++) + { + const auto a = addc(p[i + j], k); + const auto t = umul(x[i], y[j]) + uint128{a.value, a.carry}; + p[i + j] = t[0]; + k = t[1]; + } + p[num_words - 1] += x[num_words - j - 1] * y[j] + k; + } + return p; + } + + inline constexpr uint& operator*=(const uint& y) noexcept { return *this = *this * y; } }; using uint192 = uint<192>; @@ -1495,36 +1517,6 @@ inline constexpr uint<2 * N> umul(const uint& x, const uint& y) noexcept return p; } -/// Multiplication implementation using word access -/// and discarding the high part of the result product. -template -inline constexpr uint operator*(const uint& x, const uint& y) noexcept -{ - constexpr auto num_words = uint::num_words; - - uint p; - for (size_t j = 0; j < num_words; j++) - { - uint64_t k = 0; - for (size_t i = 0; i < (num_words - j - 1); i++) - { - const auto a = addc(p[i + j], k); - const auto t = umul(x[i], y[j]) + uint128{a.value, a.carry}; - p[i + j] = t[0]; - k = t[1]; - } - p[num_words - 1] += x[num_words - j - 1] * y[j] + k; - } - return p; -} - -template >::value>::type> -inline constexpr uint& operator*=(uint& x, const T& y) noexcept -{ - return x = x * y; -} - template inline constexpr uint exp(uint base, uint exponent) noexcept { @@ -1862,20 +1854,6 @@ inline constexpr uint bswap(const uint& x) noexcept // Support for type conversions for binary operators. -template >::value>::type> -inline constexpr uint operator*(const uint& x, const T& y) noexcept -{ - return x * uint(y); -} - -template >::value>::type> -inline constexpr uint operator*(const T& x, const uint& y) noexcept -{ - return uint(x) * y; -} - template >::value>::type> inline constexpr uint operator/(const uint& x, const T& y) noexcept From 1c3c141e77bfc8b76cd63d78d2f05535efd9d722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 16 May 2022 22:16:53 +0200 Subject: [PATCH 4/4] Simplify conversions for operator/ and operator% --- include/intx/intx.hpp | 70 ++++++++++--------------------------------- 1 file changed, 15 insertions(+), 55 deletions(-) diff --git a/include/intx/intx.hpp b/include/intx/intx.hpp index df6e492a..4cc95613 100644 --- a/include/intx/intx.hpp +++ b/include/intx/intx.hpp @@ -1106,6 +1106,20 @@ struct uint } inline constexpr uint& operator*=(const uint& y) noexcept { return *this = *this * y; } + + friend inline constexpr uint operator/(const uint& x, const uint& y) noexcept + { + return udivrem(x, y).quot; + } + + friend inline constexpr uint operator%(const uint& x, const uint& y) noexcept + { + return udivrem(x, y).rem; + } + + inline constexpr uint& operator/=(const uint& y) noexcept { return *this = *this / y; } + + inline constexpr uint& operator%=(const uint& y) noexcept { return *this = *this % y; } }; using uint192 = uint<192>; @@ -1761,7 +1775,7 @@ inline void udivrem_knuth( } // namespace internal template -div_result, uint> udivrem(const uint& u, const uint& v) noexcept +constexpr div_result, uint> udivrem(const uint& u, const uint& v) noexcept { auto na = internal::normalize(u, v); @@ -1815,32 +1829,6 @@ inline constexpr div_result> sdivrem(const uint& u, const uint& v) return {q_is_neg ? -res.quot : res.quot, u_is_neg ? -res.rem : res.rem}; } -template -inline constexpr uint operator/(const uint& x, const uint& y) noexcept -{ - return udivrem(x, y).quot; -} - -template -inline constexpr uint operator%(const uint& x, const uint& y) noexcept -{ - return udivrem(x, y).rem; -} - -template >::value>::type> -inline constexpr uint& operator/=(uint& x, const T& y) noexcept -{ - return x = x / y; -} - -template >::value>::type> -inline constexpr uint& operator%=(uint& x, const T& y) noexcept -{ - return x = x % y; -} - template inline constexpr uint bswap(const uint& x) noexcept { @@ -1854,34 +1842,6 @@ inline constexpr uint bswap(const uint& x) noexcept // Support for type conversions for binary operators. -template >::value>::type> -inline constexpr uint operator/(const uint& x, const T& y) noexcept -{ - return x / uint(y); -} - -template >::value>::type> -inline constexpr uint operator/(const T& x, const uint& y) noexcept -{ - return uint(x) / y; -} - -template >::value>::type> -inline constexpr uint operator%(const uint& x, const T& y) noexcept -{ - return x % uint(y); -} - -template >::value>::type> -inline constexpr uint operator%(const T& x, const uint& y) noexcept -{ - return uint(x) % y; -} - template >::value>::type> inline constexpr uint operator|(const uint& x, const T& y) noexcept