Skip to content

Commit 4bf4e48

Browse files
authored
Merge pull request #714 from cppalliance/decimal32_fast_comps_v2
Decimal32 fast comps v2
2 parents 2a17f6e + 8d6bedd commit 4bf4e48

File tree

2 files changed

+85
-46
lines changed

2 files changed

+85
-46
lines changed

include/boost/decimal/decimal32_fast.hpp

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -464,12 +464,7 @@ constexpr auto issignaling(decimal32_fast val) noexcept -> bool
464464

465465
constexpr auto isnormal(decimal32_fast val) noexcept -> bool
466466
{
467-
if (val.exponent_ <= static_cast<std::uint8_t>(detail::precision_v<decimal32> - 1))
468-
{
469-
return false;
470-
}
471-
472-
return (val.significand_ != 0) && isfinite(val);
467+
return (val.significand_ != 0) && isfinite(val) && (val.exponent_ > static_cast<std::uint8_t>(detail::precision_v<decimal32> - 1));
473468
}
474469

475470
constexpr auto isfinite(decimal32_fast val) noexcept -> bool
@@ -479,21 +474,24 @@ constexpr auto isfinite(decimal32_fast val) noexcept -> bool
479474

480475
constexpr auto operator==(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
481476
{
482-
#ifndef BOOST_DECIMAL_FAST_MATH
483-
if (isnan(lhs) || isnan(rhs))
484-
{
485-
return false;
486-
}
487-
#endif
488-
489-
return (lhs.sign_ == rhs.sign_) &
490-
(lhs.exponent_ == rhs.exponent_) &
477+
return
478+
#ifndef BOOST_DECIMAL_FAST_MATH
479+
!isnan(lhs) && !isnan(rhs) &&
480+
#endif
481+
(lhs.sign_ == rhs.sign_) &&
482+
(lhs.exponent_ == rhs.exponent_) &&
491483
(lhs.significand_ == rhs.significand_);
492484
}
493485

494486
constexpr auto operator!=(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
495487
{
496-
return !(lhs == rhs);
488+
return
489+
#ifndef BOOST_DECIMAL_FAST_MATH
490+
isnan(lhs) || isnan(rhs) ||
491+
#endif
492+
(lhs.sign_ != rhs.sign_) ||
493+
(lhs.exponent_ != rhs.exponent_) ||
494+
(lhs.significand_ != rhs.significand_);
497495
}
498496

499497
constexpr auto operator<(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
@@ -521,42 +519,37 @@ constexpr auto operator<(decimal32_fast lhs, decimal32_fast rhs) noexcept -> boo
521519
}
522520
#endif
523521

524-
if (lhs.significand_ == 0 || rhs.significand_ == 0)
525-
{
526-
if (lhs.significand_ == 0 && rhs.significand_ == 0)
527-
{
528-
#ifndef BOOST_DECIMAL_FAST_MATH
529-
return lhs.sign_ && !rhs.sign_;
530-
#else
531-
return false;
532-
#endif
533-
}
534-
return lhs.significand_ == 0 ? !rhs.sign_ : lhs.sign_;
535-
}
536-
537-
if (lhs.sign_ != rhs.sign_)
538-
{
539-
return lhs.sign_;
540-
}
541-
542-
if (lhs.exponent_ != rhs.exponent_)
543-
{
544-
return lhs.sign_ ? lhs.exponent_ > rhs.exponent_ : lhs.exponent_ < rhs.exponent_;
545-
}
546-
547-
return lhs.sign_ ? lhs.significand_ > rhs.significand_ : lhs.significand_ < rhs.significand_;
522+
return fast_type_less_parts_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_,
523+
rhs.significand_, rhs.biased_exponent(), rhs.sign_);
548524
}
549525

550526
constexpr auto operator<=(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
551527
{
552528
#ifndef BOOST_DECIMAL_FAST_MATH
553-
if (isnan(lhs) || isnan(rhs))
529+
if (!isfinite(lhs) || !isfinite(rhs))
554530
{
555-
return false;
531+
if (isnan(lhs) || isnan(rhs) ||
532+
(!lhs.isneg() && rhs.isneg()))
533+
{
534+
return false;
535+
}
536+
else if (lhs.isneg() && !rhs.isneg())
537+
{
538+
return true;
539+
}
540+
else if (isfinite(lhs) && isinf(rhs))
541+
{
542+
return !signbit(rhs);
543+
}
544+
else if (isinf(lhs) && isfinite(rhs))
545+
{
546+
return signbit(rhs);
547+
}
556548
}
557549
#endif
558550

559-
return !(rhs < lhs);
551+
return !fast_type_less_parts_impl(rhs.significand_, rhs.biased_exponent(), rhs.sign_,
552+
lhs.significand_, lhs.biased_exponent(), lhs.sign_);
560553
}
561554

562555
constexpr auto operator>(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
@@ -567,13 +560,29 @@ constexpr auto operator>(decimal32_fast lhs, decimal32_fast rhs) noexcept -> boo
567560
constexpr auto operator>=(decimal32_fast lhs, decimal32_fast rhs) noexcept -> bool
568561
{
569562
#ifndef BOOST_DECIMAL_FAST_MATH
570-
if (isnan(lhs) || isnan(rhs))
563+
if (!isfinite(lhs) || !isfinite(rhs))
571564
{
572-
return false;
565+
if (isnan(lhs) || isnan(rhs))
566+
{
567+
return false;
568+
}
569+
else if (lhs.isneg() && !rhs.isneg())
570+
{
571+
return false;
572+
}
573+
else if (isfinite(lhs) && isinf(rhs))
574+
{
575+
return signbit(rhs);
576+
}
577+
else if (isinf(lhs) && isfinite(rhs))
578+
{
579+
return !signbit(lhs);
580+
}
573581
}
574582
#endif
575583

576-
return !(lhs < rhs);
584+
return !fast_type_less_parts_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_,
585+
rhs.significand_, rhs.biased_exponent(), rhs.sign_);
577586
}
578587

579588
template <typename Integer>

include/boost/decimal/detail/comparison.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,36 @@ constexpr auto operator!=(Decimal1 lhs, Decimal2 rhs) noexcept
167167
return !(mixed_decimal_equality_impl(lhs, rhs));
168168
}
169169

170+
template <BOOST_DECIMAL_INTEGRAL T, BOOST_DECIMAL_INTEGRAL U>
171+
BOOST_DECIMAL_FORCE_INLINE constexpr auto fast_type_less_parts_impl(T lhs_sig, U lhs_exp, bool lhs_sign,
172+
T rhs_sig, U rhs_exp, bool rhs_sign) noexcept -> bool
173+
{
174+
if (lhs_sig == 0 || rhs_sig == 0)
175+
{
176+
if (lhs_sig == 0 && rhs_sig == 0)
177+
{
178+
#ifndef BOOST_DECIMAL_FAST_MATH
179+
return lhs_sign && !rhs_sign;
180+
#else
181+
return false;
182+
#endif
183+
}
184+
return lhs_sig == 0 ? !rhs_sign : lhs_sign;
185+
}
186+
187+
if (lhs_sign != rhs_sign)
188+
{
189+
return lhs_sign;
190+
}
191+
192+
if (lhs_exp != rhs_exp)
193+
{
194+
return lhs_sign ? lhs_exp > rhs_exp : lhs_exp < rhs_exp;
195+
}
196+
197+
return lhs_sign ? lhs_sig > rhs_sig : lhs_sig < rhs_sig;
198+
}
199+
170200
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE DecimalType = decimal32, BOOST_DECIMAL_INTEGRAL T1,
171201
BOOST_DECIMAL_INTEGRAL U1, BOOST_DECIMAL_INTEGRAL T2, BOOST_DECIMAL_INTEGRAL U2>
172202
constexpr auto less_parts_impl(T1 lhs_sig, U1 lhs_exp, bool lhs_sign,

0 commit comments

Comments
 (0)