From a7675df86292af4214ffeb032e90f4e6bde076ed Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 Jul 2024 14:03:49 -0400 Subject: [PATCH 1/6] Make isnormal branchless --- include/boost/decimal/decimal32_fast.hpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/include/boost/decimal/decimal32_fast.hpp b/include/boost/decimal/decimal32_fast.hpp index c1c4e9ccb..3ea6e6b3b 100644 --- a/include/boost/decimal/decimal32_fast.hpp +++ b/include/boost/decimal/decimal32_fast.hpp @@ -464,12 +464,7 @@ constexpr auto issignaling(decimal32_fast val) noexcept -> bool constexpr auto isnormal(decimal32_fast val) noexcept -> bool { - if (val.exponent_ <= static_cast(detail::precision_v - 1)) - { - return false; - } - - return (val.significand_ != 0) && isfinite(val); + return (val.significand_ != 0) && isfinite(val) && (val.exponent_ > static_cast(detail::precision_v - 1)); } constexpr auto isfinite(decimal32_fast val) noexcept -> bool From c4c0f6c5bf34961845d168964ec53d2bc076af48 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 Jul 2024 14:04:11 -0400 Subject: [PATCH 2/6] Make operator== branchless --- include/boost/decimal/decimal32_fast.hpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/include/boost/decimal/decimal32_fast.hpp b/include/boost/decimal/decimal32_fast.hpp index 3ea6e6b3b..11feeab56 100644 --- a/include/boost/decimal/decimal32_fast.hpp +++ b/include/boost/decimal/decimal32_fast.hpp @@ -474,15 +474,12 @@ constexpr auto isfinite(decimal32_fast val) noexcept -> bool constexpr auto operator==(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool { - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return (lhs.sign_ == rhs.sign_) & - (lhs.exponent_ == rhs.exponent_) & + return + #ifndef BOOST_DECIMAL_FAST_MATH + !isnan(lhs) && !isnan(rhs) && + #endif + (lhs.sign_ == rhs.sign_) && + (lhs.exponent_ == rhs.exponent_) && (lhs.significand_ == rhs.significand_); } From 6caf078f5f245b313296857f559f34d810d42eb4 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 Jul 2024 14:05:25 -0400 Subject: [PATCH 3/6] Directly implement operator!= --- include/boost/decimal/decimal32_fast.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/boost/decimal/decimal32_fast.hpp b/include/boost/decimal/decimal32_fast.hpp index 11feeab56..a6ddf1350 100644 --- a/include/boost/decimal/decimal32_fast.hpp +++ b/include/boost/decimal/decimal32_fast.hpp @@ -485,7 +485,13 @@ constexpr auto operator==(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bo constexpr auto operator!=(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool { - return !(lhs == rhs); + return + #ifndef BOOST_DECIMAL_FAST_MATH + isnan(lhs) || isnan(rhs) || + #endif + (lhs.sign_ != rhs.sign_) || + (lhs.exponent_ != rhs.exponent_) || + (lhs.significand_ != rhs.significand_); } constexpr auto operator<(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool From 453114e0a7181e237c732c4688c08cdbb37ac3bf Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 Jul 2024 14:11:06 -0400 Subject: [PATCH 4/6] Add fast type implementation of less_parts --- include/boost/decimal/decimal32_fast.hpp | 26 ++---------------- include/boost/decimal/detail/comparison.hpp | 30 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/include/boost/decimal/decimal32_fast.hpp b/include/boost/decimal/decimal32_fast.hpp index a6ddf1350..6e66b81a8 100644 --- a/include/boost/decimal/decimal32_fast.hpp +++ b/include/boost/decimal/decimal32_fast.hpp @@ -519,30 +519,8 @@ constexpr auto operator<(decimal32_fast lhs, decimal32_fast rhs) noexcept -> boo } #endif - if (lhs.significand_ == 0 || rhs.significand_ == 0) - { - if (lhs.significand_ == 0 && rhs.significand_ == 0) - { - #ifndef BOOST_DECIMAL_FAST_MATH - return lhs.sign_ && !rhs.sign_; - #else - return false; - #endif - } - return lhs.significand_ == 0 ? !rhs.sign_ : lhs.sign_; - } - - if (lhs.sign_ != rhs.sign_) - { - return lhs.sign_; - } - - if (lhs.exponent_ != rhs.exponent_) - { - return lhs.sign_ ? lhs.exponent_ > rhs.exponent_ : lhs.exponent_ < rhs.exponent_; - } - - return lhs.sign_ ? lhs.significand_ > rhs.significand_ : lhs.significand_ < rhs.significand_; + return fast_type_less_parts_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_, + rhs.significand_, rhs.biased_exponent(), rhs.sign_); } constexpr auto operator<=(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool diff --git a/include/boost/decimal/detail/comparison.hpp b/include/boost/decimal/detail/comparison.hpp index c74637178..091b81501 100644 --- a/include/boost/decimal/detail/comparison.hpp +++ b/include/boost/decimal/detail/comparison.hpp @@ -167,6 +167,36 @@ constexpr auto operator!=(Decimal1 lhs, Decimal2 rhs) noexcept return !(mixed_decimal_equality_impl(lhs, rhs)); } +template +BOOST_DECIMAL_FORCE_INLINE constexpr auto fast_type_less_parts_impl(T lhs_sig, U lhs_exp, bool lhs_sign, + T rhs_sig, U rhs_exp, bool rhs_sign) noexcept -> bool +{ + if (lhs_sig == 0 || rhs_sig == 0) + { + if (lhs_sig == 0 && rhs_sig == 0) + { + #ifndef BOOST_DECIMAL_FAST_MATH + return lhs_sign && !rhs_sign; + #else + return false; + #endif + } + return lhs_sig == 0 ? !rhs_sign : lhs_sign; + } + + if (lhs_sign != rhs_sign) + { + return lhs_sign; + } + + if (lhs_exp != rhs_exp) + { + return lhs_sign ? lhs_exp > rhs_exp : lhs_exp < rhs_exp; + } + + return lhs_sign ? lhs_sig > rhs_sig : lhs_sig < rhs_sig; +} + template constexpr auto less_parts_impl(T1 lhs_sig, U1 lhs_exp, bool lhs_sign, From 9ffb6965ae6470bd40635d7f773501b6e99cebc5 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 16 Jul 2024 15:21:41 -0400 Subject: [PATCH 5/6] Improve operator<= --- include/boost/decimal/decimal32_fast.hpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/include/boost/decimal/decimal32_fast.hpp b/include/boost/decimal/decimal32_fast.hpp index 6e66b81a8..aef560447 100644 --- a/include/boost/decimal/decimal32_fast.hpp +++ b/include/boost/decimal/decimal32_fast.hpp @@ -526,13 +526,30 @@ constexpr auto operator<(decimal32_fast lhs, decimal32_fast rhs) noexcept -> boo constexpr auto operator<=(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool { #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) + if (!isfinite(lhs) || !isfinite(rhs)) { - return false; + if (isnan(lhs) || isnan(rhs) || + (!lhs.isneg() && rhs.isneg())) + { + return false; + } + else if (lhs.isneg() && !rhs.isneg()) + { + return true; + } + else if (isfinite(lhs) && isinf(rhs)) + { + return !signbit(rhs); + } + else if (isinf(lhs) && isfinite(rhs)) + { + return signbit(rhs); + } } #endif - return !(rhs < lhs); + return !fast_type_less_parts_impl(rhs.significand_, rhs.biased_exponent(), rhs.sign_, + lhs.significand_, lhs.biased_exponent(), lhs.sign_); } constexpr auto operator>(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool From 8d6bedda361fdefc82a3310503e698582ce429ec Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 17 Jul 2024 13:18:58 -0400 Subject: [PATCH 6/6] Improve operator >= --- include/boost/decimal/decimal32_fast.hpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/include/boost/decimal/decimal32_fast.hpp b/include/boost/decimal/decimal32_fast.hpp index aef560447..8ac613880 100644 --- a/include/boost/decimal/decimal32_fast.hpp +++ b/include/boost/decimal/decimal32_fast.hpp @@ -560,13 +560,29 @@ constexpr auto operator>(decimal32_fast lhs, decimal32_fast rhs) noexcept -> boo constexpr auto operator>=(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool { #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) + if (!isfinite(lhs) || !isfinite(rhs)) { - return false; + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + else if (lhs.isneg() && !rhs.isneg()) + { + return false; + } + else if (isfinite(lhs) && isinf(rhs)) + { + return signbit(rhs); + } + else if (isinf(lhs) && isfinite(rhs)) + { + return !signbit(lhs); + } } #endif - return !(lhs < rhs); + return !fast_type_less_parts_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_, + rhs.significand_, rhs.biased_exponent(), rhs.sign_); } template