Skip to content

Commit b202107

Browse files
authored
Merge pull request #693 from cppalliance/sub32
Remove recursive call from 32 bit operator-
2 parents 73669da + 14067a4 commit b202107

File tree

3 files changed

+22
-56
lines changed

3 files changed

+22
-56
lines changed

include/boost/decimal/decimal32.hpp

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -944,11 +944,6 @@ constexpr auto operator-(decimal32 lhs, decimal32 rhs) noexcept -> decimal32
944944
}
945945
#endif
946946

947-
if (!lhs.isneg() && rhs.isneg())
948-
{
949-
return lhs + (-rhs);
950-
}
951-
952947
const bool abs_lhs_bigger {abs(lhs) > abs(rhs)};
953948

954949
auto sig_lhs {lhs.full_significand()};
@@ -959,9 +954,9 @@ constexpr auto operator-(decimal32 lhs, decimal32 rhs) noexcept -> decimal32
959954
auto exp_rhs {rhs.biased_exponent()};
960955
detail::normalize(sig_rhs, exp_rhs);
961956

962-
return detail::sub_impl<decimal32>(sig_lhs, exp_lhs, lhs.isneg(),
963-
sig_rhs, exp_rhs, rhs.isneg(),
964-
abs_lhs_bigger);
957+
return detail::d32_sub_impl<decimal32>(sig_lhs, exp_lhs, lhs.isneg(),
958+
sig_rhs, exp_rhs, rhs.isneg(),
959+
abs_lhs_bigger);
965960
}
966961

967962
template <typename Integer>
@@ -978,11 +973,6 @@ constexpr auto operator-(decimal32 lhs, Integer rhs) noexcept
978973
}
979974
#endif
980975

981-
if (!lhs.isneg() && (rhs < 0))
982-
{
983-
return lhs + detail::make_positive_unsigned(rhs);
984-
}
985-
986976
auto sig_rhs {static_cast<promoted_significand_type>(detail::make_positive_unsigned(rhs))};
987977
const bool abs_lhs_bigger {abs(lhs) > sig_rhs};
988978

@@ -994,9 +984,9 @@ constexpr auto operator-(decimal32 lhs, Integer rhs) noexcept
994984
detail::normalize(sig_rhs, exp_rhs);
995985
auto final_sig_rhs {static_cast<decimal32::significand_type>(sig_rhs)};
996986

997-
return detail::sub_impl<decimal32>(sig_lhs, exp_lhs, lhs.isneg(),
998-
final_sig_rhs, exp_rhs, (rhs < 0),
999-
abs_lhs_bigger);
987+
return detail::d32_sub_impl<decimal32>(sig_lhs, exp_lhs, lhs.isneg(),
988+
final_sig_rhs, exp_rhs, (rhs < 0),
989+
abs_lhs_bigger);
1000990
}
1001991

1002992
template <typename Integer>
@@ -1012,12 +1002,7 @@ constexpr auto operator-(Integer lhs, decimal32 rhs) noexcept
10121002
return rhs;
10131003
}
10141004
#endif
1015-
1016-
if (lhs >= 0 && rhs.isneg())
1017-
{
1018-
return lhs + (-rhs);
1019-
}
1020-
1005+
10211006
auto sig_lhs {static_cast<promoted_significand_type>(detail::make_positive_unsigned(lhs))};
10221007
const bool abs_lhs_bigger {sig_lhs > abs(rhs)};
10231008

@@ -1029,9 +1014,9 @@ constexpr auto operator-(Integer lhs, decimal32 rhs) noexcept
10291014
auto exp_rhs {rhs.biased_exponent()};
10301015
detail::normalize(sig_rhs, exp_rhs);
10311016

1032-
return detail::sub_impl<decimal32>(final_sig_lhs, exp_lhs, (lhs < 0),
1033-
sig_rhs, exp_rhs, rhs.isneg(),
1034-
abs_lhs_bigger);
1017+
return detail::d32_sub_impl<decimal32>(final_sig_lhs, exp_lhs, (lhs < 0),
1018+
sig_rhs, exp_rhs, rhs.isneg(),
1019+
abs_lhs_bigger);
10351020
}
10361021

10371022
constexpr auto decimal32::operator--() noexcept -> decimal32&

include/boost/decimal/decimal32_fast.hpp

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -820,18 +820,11 @@ constexpr auto operator-(decimal32_fast lhs, decimal32_fast rhs) noexcept -> dec
820820
}
821821
#endif
822822

823-
if (!lhs.isneg() && rhs.isneg())
824-
{
825-
return lhs + (-rhs);
826-
}
827-
828-
const bool abs_lhs_bigger {abs(lhs) > abs(rhs)};
829-
830-
return detail::sub_impl<decimal32_fast>(
823+
return detail::d32_sub_impl<decimal32_fast>(
831824
lhs.significand_, lhs.biased_exponent(), lhs.sign_,
832825
rhs.significand_, rhs.biased_exponent(), rhs.sign_,
833-
abs_lhs_bigger
834-
);
826+
abs(lhs) > abs(rhs)
827+
);
835828
}
836829

837830
template <typename Integer>
@@ -850,18 +843,13 @@ constexpr auto operator-(decimal32_fast lhs, Integer rhs) noexcept
850843

851844
auto sig_rhs {static_cast<promoted_significand_type>(detail::make_positive_unsigned(rhs))};
852845

853-
if (!lhs.isneg() && (rhs < 0))
854-
{
855-
return lhs + sig_rhs;
856-
}
857-
858846
const bool abs_lhs_bigger {abs(lhs) > sig_rhs};
859847

860848
exp_type exp_rhs {0};
861849
detail::normalize(sig_rhs, exp_rhs);
862850
auto final_sig_rhs {static_cast<decimal32_fast::significand_type>(detail::make_positive_unsigned(sig_rhs))};
863851

864-
return detail::sub_impl<decimal32_fast>(
852+
return detail::d32_sub_impl<decimal32_fast>(
865853
lhs.significand_, lhs.biased_exponent(), lhs.sign_,
866854
final_sig_rhs, exp_rhs, (rhs < 0),
867855
abs_lhs_bigger);
@@ -881,23 +869,18 @@ constexpr auto operator-(Integer lhs, decimal32_fast rhs) noexcept
881869
}
882870
#endif
883871

884-
if (lhs >= 0 && rhs.isneg())
885-
{
886-
return lhs + (-rhs);
887-
}
888-
889872
auto sig_lhs {static_cast<promoted_significand_type>(detail::make_positive_unsigned(lhs))};
890873
const bool abs_lhs_bigger {sig_lhs > abs(rhs)};
891874

892875
exp_type exp_lhs {0};
893876
detail::normalize(sig_lhs, exp_lhs);
894877
auto final_sig_lhs {static_cast<decimal32_fast::significand_type>(detail::make_positive_unsigned(sig_lhs))};
895878

896-
return detail::sub_impl<decimal32_fast>(
879+
return detail::d32_sub_impl<decimal32_fast>(
897880
final_sig_lhs, exp_lhs, (lhs < 0),
898881
rhs.significand_, rhs.biased_exponent(), rhs.sign_,
899882
abs_lhs_bigger
900-
);
883+
);
901884
}
902885

903886
constexpr auto operator*(decimal32_fast lhs, decimal32_fast rhs) noexcept -> decimal32_fast

include/boost/decimal/detail/sub_impl.hpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ namespace decimal {
1818
namespace detail {
1919

2020
template <typename ReturnType, typename T, typename U>
21-
BOOST_DECIMAL_FORCE_INLINE constexpr auto sub_impl(T lhs_sig, U lhs_exp, bool lhs_sign,
22-
T rhs_sig, U rhs_exp, bool rhs_sign,
23-
bool abs_lhs_bigger) noexcept -> ReturnType
21+
BOOST_DECIMAL_FORCE_INLINE constexpr auto d32_sub_impl(T lhs_sig, U lhs_exp, bool lhs_sign,
22+
T rhs_sig, U rhs_exp, bool rhs_sign,
23+
bool abs_lhs_bigger) noexcept -> ReturnType
2424
{
2525
using sub_type = std::int_fast32_t;
2626

2727
auto delta_exp {lhs_exp > rhs_exp ? lhs_exp - rhs_exp : rhs_exp - lhs_exp};
28-
auto signed_sig_lhs {detail::make_signed_value(lhs_sig, lhs_sign)};
29-
auto signed_sig_rhs {detail::make_signed_value(rhs_sig, rhs_sign)};
28+
auto signed_sig_lhs {detail::make_signed_value(static_cast<sub_type>(lhs_sig), lhs_sign)};
29+
auto signed_sig_rhs {detail::make_signed_value(static_cast<sub_type>(rhs_sig), rhs_sign)};
3030

3131
if (delta_exp > detail::precision + 1)
3232
{
@@ -74,9 +74,7 @@ BOOST_DECIMAL_FORCE_INLINE constexpr auto sub_impl(T lhs_sig, U lhs_exp, bool lh
7474

7575
// Both of the significands are less than 9'999'999, so we can safely
7676
// cast them to signed 32-bit ints to calculate the new significand
77-
const auto new_sig = (rhs_sign && !lhs_sign) ?
78-
static_cast<sub_type>(signed_sig_lhs) + static_cast<sub_type>(signed_sig_rhs) :
79-
static_cast<sub_type>(signed_sig_lhs) - static_cast<sub_type>(signed_sig_rhs);
77+
const auto new_sig {signed_sig_lhs - signed_sig_rhs};
8078

8179
const auto new_exp {abs_lhs_bigger ? lhs_exp : rhs_exp};
8280
const auto new_sign {new_sig < 0};

0 commit comments

Comments
 (0)