@@ -121,6 +121,9 @@ BOOST_DECIMAL_EXPORT class decimal_fast32_t final
121121 template <typename ReturnType, typename T>
122122 friend constexpr auto detail::add_impl (const T& lhs, const T& rhs) noexcept -> ReturnType;
123123
124+ template <typename ReturnType, typename T>
125+ friend constexpr auto detail::mul_impl (const T& lhs, const T& rhs) noexcept -> ReturnType;
126+
124127 template <BOOST_DECIMAL_FAST_DECIMAL_FLOATING_TYPE DecimalType>
125128 BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_equality_impl (const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool;
126129
@@ -144,6 +147,9 @@ BOOST_DECIMAL_EXPORT class decimal_fast32_t final
144147 template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE TargetDecimalType>
145148 friend constexpr auto detail::to_chars_hex_impl (char * first, char * last, const TargetDecimalType& value) noexcept -> to_chars_result;
146149
150+ template <typename DecimalType, typename T>
151+ friend constexpr auto detail::generic_div_impl (const T& lhs, const T& rhs) noexcept -> DecimalType;
152+
147153public:
148154 constexpr decimal_fast32_t () noexcept = default;
149155
@@ -413,7 +419,7 @@ constexpr decimal_fast32_t::decimal_fast32_t(T1 coeff, T2 exp, bool sign) noexce
413419 sign_ = sign;
414420
415421 // Normalize in the constructor, so we never have to worry about it again
416- detail::normalize<decimal32_t >(min_coeff, exp, sign);
422+ detail::normalize<decimal_fast32_t >(min_coeff, exp, sign);
417423
418424 significand_ = static_cast <significand_type>(min_coeff);
419425
@@ -902,26 +908,7 @@ constexpr auto operator*(const decimal_fast32_t lhs, const decimal_fast32_t rhs)
902908 }
903909 #endif
904910
905- using mul_type = std::uint_fast64_t ;
906-
907- const auto isneg {lhs.sign_ != rhs.sign_ };
908- constexpr auto ten_pow_seven {detail::pow10 (static_cast <mul_type>(6 ))};
909- constexpr auto ten_pow_seven_exp_offset {95 };
910- constexpr auto ten_pow_six {detail::pow10 (static_cast <mul_type>(5 ))};
911- constexpr auto ten_pow_six_exp_offset {96 };
912-
913- auto res_sig {(static_cast <mul_type>(lhs.significand_ ) * static_cast <mul_type>(rhs.significand_ ))};
914- const bool res_sig_14_dig {res_sig > UINT64_C (10000000000000 )};
915- res_sig /= res_sig_14_dig ? ten_pow_seven : ten_pow_six;
916- auto res_exp {lhs.exponent_ + rhs.exponent_ };
917- res_exp -= res_sig_14_dig ? ten_pow_seven_exp_offset : ten_pow_six_exp_offset;
918-
919- res_exp += detail::fenv_round<decimal_fast32_t >(res_sig, isneg);
920-
921- BOOST_DECIMAL_ASSERT (res_sig >= 1'000'000 || res_sig == 0U );
922- BOOST_DECIMAL_ASSERT (res_exp <= 9'999'999 || res_sig == 0U );
923-
924- return direct_init (static_cast <decimal_fast32_t ::significand_type>(res_sig), static_cast <decimal_fast32_t ::exponent_type>(res_exp) , isneg);
911+ return detail::mul_impl<decimal_fast32_t >(lhs, rhs);
925912}
926913
927914template <typename Integer>
@@ -959,9 +946,9 @@ constexpr auto operator*(const Integer lhs, const decimal_fast32_t rhs) noexcept
959946
960947constexpr auto div_impl (const decimal_fast32_t lhs, const decimal_fast32_t rhs, decimal_fast32_t & q, decimal_fast32_t & r) noexcept -> void
961948{
962- constexpr decimal_fast32_t zero {0 , 0 };
963-
964949 #ifndef BOOST_DECIMAL_FAST_MATH
950+ constexpr decimal_fast32_t zero {0 , 0 };
951+
965952 const bool sign {lhs.isneg () != rhs.isneg ()};
966953 constexpr decimal_fast32_t nan {direct_init (detail::d32_fast_qnan, UINT8_C (0 ), false )};
967954 constexpr decimal_fast32_t inf {direct_init (detail::d32_fast_inf, UINT8_C (0 ), false )};
@@ -1007,43 +994,7 @@ constexpr auto div_impl(const decimal_fast32_t lhs, const decimal_fast32_t rhs,
1007994 static_cast <void >(r);
1008995 #endif
1009996
1010- #ifdef BOOST_DECIMAL_DEBUG
1011- std::cerr << " sig lhs: " << sig_lhs
1012- << " \n exp lhs: " << exp_lhs
1013- << " \n sig rhs: " << sig_rhs
1014- << " \n exp rhs: " << exp_rhs << std::endl;
1015- #endif
1016-
1017- using local_signed_exponent_type = std::common_type_t <std::int_fast32_t , int >;
1018-
1019- static_assert (sizeof (local_signed_exponent_type) >= 4 , " Error in local exponent type definition" );
1020-
1021- // We promote to uint64 since the significands are currently 32-bits
1022- // By appending enough zeros to the LHS we end up finding what we need anyway
1023- constexpr auto ten_pow_precision {detail::pow10 (static_cast <std::uint_fast64_t >(detail::precision_v<decimal32_t >))};
1024- const auto big_sig_lhs {static_cast <std::uint_fast64_t >(lhs.significand_ ) * ten_pow_precision};
1025- auto res_sig {big_sig_lhs / static_cast <std::uint_fast64_t >(rhs.significand_ )};
1026- local_signed_exponent_type res_exp {static_cast <local_signed_exponent_type>(lhs.exponent_ ) - static_cast <local_signed_exponent_type>(rhs.exponent_ ) + 94 };
1027- const auto isneg {lhs.sign_ != rhs.sign_ };
1028-
1029- // If we have 8 figures round it down to 7
1030- if (res_sig >= UINT64_C (10'000'000 ))
1031- {
1032- res_exp += detail::fenv_round<decimal_fast32_t >(res_sig, isneg);
1033- }
1034-
1035- BOOST_DECIMAL_ASSERT (res_sig >= 1'000'000 || res_sig == 0U );
1036- BOOST_DECIMAL_ASSERT (res_exp <= 9'999'999 || res_sig == 0U );
1037-
1038- if (BOOST_DECIMAL_LIKELY (res_exp >= 0 ))
1039- {
1040- q = direct_init (static_cast <decimal_fast32_t ::significand_type>(res_sig), static_cast <decimal_fast32_t ::exponent_type>(res_exp), isneg);
1041- }
1042- else
1043- {
1044- // Flush to zero
1045- q = zero;
1046- }
997+ q = detail::generic_div_impl<decimal_fast32_t >(lhs, rhs);
1047998}
1048999
10491000constexpr auto mod_impl (const decimal_fast32_t lhs, const decimal_fast32_t rhs, const decimal_fast32_t & q, decimal_fast32_t & r) noexcept -> void
0 commit comments