Skip to content

Commit

Permalink
Merge pull request #867 from cppalliance/843
Browse files Browse the repository at this point in the history
  • Loading branch information
mborland authored Feb 19, 2025
2 parents b1ec783 + 35c3ce6 commit 866c936
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 236 deletions.
83 changes: 12 additions & 71 deletions include/boost/decimal/decimal128_fast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ BOOST_DECIMAL_EXPORT class decimal128_fast final
friend constexpr auto to_dpd_d128(DecimalType val) noexcept
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, detail::uint128);

template <BOOST_DECIMAL_FAST_DECIMAL_FLOATING_TYPE DecimalType>
BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_equality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool;

template <BOOST_DECIMAL_FAST_DECIMAL_FLOATING_TYPE DecimalType>
BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_inequality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool;

template <BOOST_DECIMAL_FAST_DECIMAL_FLOATING_TYPE DecimalType>
BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_less_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool;

public:
constexpr decimal128_fast() noexcept = default;

Expand Down Expand Up @@ -535,28 +544,7 @@ 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))
{
return false;
}
#endif

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

return lhs.sign_ == rhs.sign_;
return fast_equality_impl(lhs, rhs);
}

template <typename Integer>
Expand All @@ -575,7 +563,7 @@ constexpr auto operator==(Integer lhs, decimal128_fast rhs) noexcept

constexpr auto operator!=(const decimal128_fast& lhs, const decimal128_fast& rhs) noexcept -> bool
{
return !(lhs == rhs);
return fast_inequality_impl(lhs, rhs);
}

template <typename Integer>
Expand All @@ -594,54 +582,7 @@ constexpr auto operator!=(Integer lhs, decimal128_fast rhs) noexcept

constexpr auto operator<(const decimal128_fast& lhs, const decimal128_fast& rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
if (not_finite(lhs) || not_finite(rhs))
{
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

// Needed to correctly compare signed and unsigned zeros
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_less_impl(lhs, rhs);
}

template <typename Integer>
Expand Down
119 changes: 26 additions & 93 deletions include/boost/decimal/decimal32_fast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <boost/decimal/detail/promote_significand.hpp>
#include <boost/decimal/detail/ryu/ryu_generic_128.hpp>
#include <boost/decimal/detail/promotion.hpp>
#include <boost/decimal/detail/comparison.hpp>

#ifndef BOOST_DECIMAL_BUILD_MODULE
#include <limits>
Expand Down Expand Up @@ -114,6 +115,17 @@ BOOST_DECIMAL_EXPORT class decimal32_fast final
template <typename ReturnType, typename T>
friend constexpr auto detail::d32_add_impl(const T& lhs, const T& rhs) noexcept -> ReturnType;

template <BOOST_DECIMAL_FAST_DECIMAL_FLOATING_TYPE DecimalType>
BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_equality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool;

template <BOOST_DECIMAL_FAST_DECIMAL_FLOATING_TYPE DecimalType>
BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_inequality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool;

template <BOOST_DECIMAL_FAST_DECIMAL_FLOATING_TYPE DecimalType>
BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_less_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool;

friend constexpr auto not_finite(const decimal32_fast& val) noexcept -> bool;

public:
constexpr decimal32_fast() noexcept = default;

Expand Down Expand Up @@ -492,99 +504,36 @@ constexpr auto isfinite(decimal32_fast val) noexcept -> bool
return val.significand_ < detail::d32_fast_inf;
}

constexpr auto operator==(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
constexpr auto not_finite(const decimal32_fast& val) noexcept -> bool
{
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 val.significand_ >= detail::d32_fast_inf;
}

return lhs.sign_ == rhs.sign_;
constexpr auto operator==(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
{
return fast_equality_impl(lhs, rhs);
}

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_);
return fast_inequality_impl(lhs, rhs);
}

constexpr auto operator<(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
if (!isfinite(lhs) || !isfinite(rhs))
{
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 fast_type_less_parts_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_,
rhs.significand_, rhs.biased_exponent(), rhs.sign_);
return fast_less_impl(lhs, rhs);
}

constexpr auto operator<=(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
if (!isfinite(lhs) || !isfinite(rhs))
if (isnan(lhs) || isnan(rhs))
{
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);
}
return false;
}
#endif

return !fast_type_less_parts_impl(rhs.significand_, rhs.biased_exponent(), rhs.sign_,
lhs.significand_, lhs.biased_exponent(), lhs.sign_);
return !(rhs < lhs);
}

constexpr auto operator>(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
Expand All @@ -595,29 +544,13 @@ 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 (!isfinite(lhs) || !isfinite(rhs))
if (isnan(lhs) || isnan(rhs))
{
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);
}
return false;
}
#endif

return !fast_type_less_parts_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_,
rhs.significand_, rhs.biased_exponent(), rhs.sign_);
return !(lhs < rhs);
}

template <typename Integer>
Expand Down
Loading

0 comments on commit 866c936

Please sign in to comment.