|
15 | 15 | #include <boost/decimal/detail/cmath/isfinite.hpp> |
16 | 16 | #include <boost/decimal/detail/concepts.hpp> |
17 | 17 | #include <boost/decimal/detail/power_tables.hpp> |
| 18 | +#include <boost/decimal/detail/emulated128.hpp> |
18 | 19 |
|
19 | 20 | #ifndef BOOST_DECIMAL_BUILD_MODULE |
20 | 21 | #include <limits> |
@@ -51,17 +52,18 @@ BOOST_DECIMAL_FORCE_INLINE constexpr auto equality_impl(DecimalType lhs, Decimal |
51 | 52 | const auto lhs_exp {lhs.biased_exponent()}; |
52 | 53 | const auto rhs_exp {rhs.biased_exponent()}; |
53 | 54 |
|
| 55 | + auto lhs_sig {lhs.full_significand()}; |
| 56 | + auto rhs_sig {rhs.full_significand()}; |
| 57 | + |
54 | 58 | const auto delta_exp {lhs_exp - rhs_exp}; |
55 | 59 |
|
56 | | - if (delta_exp > detail::precision_v<DecimalType> || delta_exp < -detail::precision_v<DecimalType>) |
| 60 | + if (delta_exp > detail::precision_v<DecimalType> || delta_exp < -detail::precision_v<DecimalType> || |
| 61 | + ((lhs_sig == static_cast<comp_type>(0)) ^ (rhs_sig == static_cast<comp_type>(0)))) |
57 | 62 | { |
58 | 63 | return false; |
59 | 64 | } |
60 | 65 |
|
61 | 66 | // Step 5: Normalize the significand and compare |
62 | | - auto lhs_sig {lhs.full_significand()}; |
63 | | - auto rhs_sig {rhs.full_significand()}; |
64 | | - |
65 | 67 | delta_exp >= 0 ? lhs_sig *= detail::pow10(static_cast<comp_type>(delta_exp)) : |
66 | 68 | rhs_sig *= detail::pow10(static_cast<comp_type>(-delta_exp)); |
67 | 69 |
|
@@ -244,7 +246,19 @@ BOOST_DECIMAL_FORCE_INLINE constexpr auto fast_type_less_parts_impl(T lhs_sig, U |
244 | 246 | template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE DecimalType> |
245 | 247 | constexpr auto sequential_less_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool |
246 | 248 | { |
247 | | - using comp_type = std::uint_fast64_t; |
| 249 | + using comp_type = std::conditional_t<std::is_same<DecimalType, decimal32>::value, std::uint_fast64_t, |
| 250 | + // GCC less than 10 in non-GNU mode, Clang < 10 and MinGW all have issues with the built-in u128, |
| 251 | + // so use the emulated one |
| 252 | + #if defined(BOOST_DECIMAL_HAS_INT128) |
| 253 | + #if ( (defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 10) || (defined(__clang__) && __clang_major__ < 13) ) |
| 254 | + detail::uint128 |
| 255 | + # else |
| 256 | + detail::uint128_t |
| 257 | + # endif |
| 258 | + #else |
| 259 | + detail::uint128 |
| 260 | + #endif |
| 261 | + >; |
248 | 262 |
|
249 | 263 | // Step 1: Handle our non-finite values in their own calling functions |
250 | 264 |
|
@@ -278,7 +292,7 @@ constexpr auto sequential_less_impl(DecimalType lhs, DecimalType rhs) noexcept - |
278 | 292 | auto rhs_exp {rhs.biased_exponent()}; |
279 | 293 |
|
280 | 294 | const auto delta_exp {lhs_exp - rhs_exp}; |
281 | | - constexpr auto max_delta_diff {std::numeric_limits<std::uint_fast64_t>::digits10 - detail::precision_v<DecimalType>}; |
| 295 | + constexpr auto max_delta_diff {std::numeric_limits<comp_type>::digits10 - detail::precision_v<DecimalType>}; |
282 | 296 |
|
283 | 297 | if (delta_exp > max_delta_diff || delta_exp < -max_delta_diff) |
284 | 298 | { |
|
0 commit comments