Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions include/boost/decimal/decimal128.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ BOOST_DECIMAL_EXPORT class decimal128 final
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE TargetType, BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal>
friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType;

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE DecimalType>
friend BOOST_DECIMAL_FORCE_INLINE constexpr auto equality_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool;

// Equality template between any integer type and decimal128
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, BOOST_DECIMAL_INTEGRAL Integer>
friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept
Expand Down Expand Up @@ -1202,16 +1205,7 @@ constexpr auto operator-(decimal128 rhs) noexcept-> decimal128

constexpr auto operator==(decimal128 lhs, decimal128 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
// Check for IEEE requirement that nan != nan
if (isnan(lhs) || isnan(rhs))
{
return false;
}
#endif

return equal_parts_impl<decimal128>(lhs.full_significand(), lhs.biased_exponent(), lhs.isneg(),
rhs.full_significand(), rhs.biased_exponent(), rhs.isneg());
return equality_impl(lhs, rhs);
}

template <typename Integer>
Expand Down
20 changes: 16 additions & 4 deletions include/boost/decimal/decimal128_fast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,16 +537,28 @@ constexpr auto not_finite(const decimal128_fast& val) noexcept -> bool

constexpr auto operator==(const decimal128_fast& lhs, const decimal128_fast& rhs) noexcept -> bool
{
if (lhs.exponent_ != rhs.exponent_)
{
return false;
}
if (lhs.significand_ != rhs.significand_)
{
return false;
}

#ifndef BOOST_DECIMAL_FAST_MATH
if (isnan(lhs) || isnan(rhs))
if (isnan(lhs))
{
return false;
}
#endif

return lhs.sign_ == rhs.sign_ &&
lhs.exponent_ == rhs.exponent_ &&
lhs.significand_ == rhs.significand_;
if (lhs.significand_ == 0)
{
return true; // -0 == +0
}

return lhs.sign_ == rhs.sign_;
}

template <typename Integer>
Expand Down
29 changes: 22 additions & 7 deletions include/boost/decimal/decimal32_fast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,13 +490,28 @@ constexpr auto isfinite(decimal32_fast val) noexcept -> bool

constexpr auto operator==(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
{
return
#ifndef BOOST_DECIMAL_FAST_MATH
!isnan(lhs) && !isnan(rhs) &&
#endif
(lhs.sign_ == rhs.sign_) &&
(lhs.exponent_ == rhs.exponent_) &&
(lhs.significand_ == rhs.significand_);
if (lhs.exponent_ != rhs.exponent_)
{
return false;
}
if (lhs.significand_ != rhs.significand_)
{
return false;
}

#ifndef BOOST_DECIMAL_FAST_MATH
if (isnan(lhs))
{
return false;
}
#endif

if (lhs.significand_ == 0)
{
return true; // -0 == +0
}

return lhs.sign_ == rhs.sign_;
}

constexpr auto operator!=(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
Expand Down
20 changes: 16 additions & 4 deletions include/boost/decimal/decimal64_fast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,16 +518,28 @@ constexpr auto not_finite(decimal64_fast val) noexcept -> bool

constexpr auto operator==(decimal64_fast lhs, decimal64_fast rhs) noexcept -> bool
{
if (lhs.exponent_ != rhs.exponent_)
{
return false;
}
if (lhs.significand_ != rhs.significand_)
{
return false;
}

#ifndef BOOST_DECIMAL_FAST_MATH
if (isnan(lhs) || isnan(rhs))
if (isnan(lhs))
{
return false;
}
#endif

return lhs.sign_ == rhs.sign_ &&
lhs.exponent_ == rhs.exponent_ &&
lhs.significand_ == rhs.significand_;
if (lhs.significand_ == 0)
{
return true; // -0 == +0
}

return lhs.sign_ == rhs.sign_;
}

template <typename Integer>
Expand Down
28 changes: 17 additions & 11 deletions include/boost/decimal/detail/comparison.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,21 @@ BOOST_DECIMAL_FORCE_INLINE constexpr auto equality_impl(DecimalType lhs, Decimal
}
#endif

// Step 3: Check signs
// Step 2: Fast path
if (lhs.bits_ == rhs.bits_)
{
return true;
}

// Step 3: Check -0 == +0
auto lhs_sig {lhs.full_significand()};
auto rhs_sig {rhs.full_significand()};
if (lhs_sig == 0 && rhs_sig == 0)
{
return true;
}

// Step 4: Check signs
const auto lhs_neg {lhs.isneg()};
const auto rhs_neg {rhs.isneg()};

Expand All @@ -47,27 +61,19 @@ BOOST_DECIMAL_FORCE_INLINE constexpr auto equality_impl(DecimalType lhs, Decimal
return false;
}

// Step 4: Check the exponents
// Step 5: Check the exponents
// If the difference is greater than we can represent in the significand than we can assume they are different
const auto lhs_exp {lhs.biased_exponent()};
const auto rhs_exp {rhs.biased_exponent()};

auto lhs_sig {lhs.full_significand()};
auto rhs_sig {rhs.full_significand()};

const auto delta_exp {lhs_exp - rhs_exp};

if (lhs_sig == 0 && rhs_sig == 0)
{
// The difference in exponent is irrelevant here
return true;
}
if (delta_exp > detail::precision_v<DecimalType> || delta_exp < -detail::precision_v<DecimalType>)
{
return false;
}

// Step 5: Normalize the significand and compare
// Step 6: Normalize the significand and compare
// Instead of multiplying the larger number, divide the smaller one
if (delta_exp >= 0)
{
Expand Down
4 changes: 4 additions & 0 deletions test/random_decimal128_comp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,5 +574,9 @@ int main()
random_mixed_SPACESHIP(std::numeric_limits<unsigned long long>::min(), std::numeric_limits<unsigned long long>::max());
#endif

constexpr auto pos_zero = boost::decimal::decimal128{0, 0, false};
constexpr auto neg_zero = boost::decimal::decimal128{0, 0, true};
BOOST_TEST(pos_zero == neg_zero);

return boost::report_errors();
}
4 changes: 4 additions & 0 deletions test/random_decimal128_fast_comp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,5 +593,9 @@ int main()
random_mixed_SPACESHIP(std::numeric_limits<unsigned long long>::min(), std::numeric_limits<unsigned long long>::max());
#endif

constexpr auto pos_zero = boost::decimal::decimal128_fast{0, 0, false};
constexpr auto neg_zero = boost::decimal::decimal128_fast{0, 0, true};
BOOST_TEST_EQ(pos_zero, neg_zero);

return boost::report_errors();
}
4 changes: 4 additions & 0 deletions test/random_decimal32_comp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,5 +606,9 @@ int main()
random_mixed_SPACESHIP(std::numeric_limits<unsigned long long>::min(), std::numeric_limits<unsigned long long>::max());
#endif

constexpr auto pos_zero = boost::decimal::decimal32{0, 0, false};
constexpr auto neg_zero = boost::decimal::decimal32{0, 0, true};
BOOST_TEST_EQ(pos_zero, neg_zero);

return boost::report_errors();
}
4 changes: 4 additions & 0 deletions test/random_decimal32_fast_comp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,5 +593,9 @@ int main()
random_mixed_SPACESHIP(std::numeric_limits<unsigned long long>::min(), std::numeric_limits<unsigned long long>::max());
#endif

constexpr auto pos_zero = boost::decimal::decimal32_fast{0, 0, false};
constexpr auto neg_zero = boost::decimal::decimal32_fast{0, 0, true};
BOOST_TEST_EQ(pos_zero, neg_zero);

return boost::report_errors();
}
4 changes: 4 additions & 0 deletions test/random_decimal64_comp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,5 +571,9 @@ int main()
random_mixed_SPACESHIP(std::numeric_limits<unsigned long long>::min(), std::numeric_limits<unsigned long long>::max());
#endif

constexpr auto pos_zero = boost::decimal::decimal64{0, 0, false};
constexpr auto neg_zero = boost::decimal::decimal64{0, 0, true};
BOOST_TEST_EQ(pos_zero, neg_zero);

return boost::report_errors();
}
4 changes: 4 additions & 0 deletions test/random_decimal64_fast_comp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,5 +593,9 @@ int main()
random_mixed_SPACESHIP(std::numeric_limits<unsigned long long>::min(), std::numeric_limits<unsigned long long>::max());
#endif

constexpr auto pos_zero = boost::decimal::decimal64_fast{0, 0, false};
constexpr auto neg_zero = boost::decimal::decimal64_fast{0, 0, true};
BOOST_TEST_EQ(pos_zero, neg_zero);

return boost::report_errors();
}
Loading