@@ -745,7 +745,7 @@ constexpr decimal128_t::decimal128_t(T1 coeff, T2 exp, bool sign) noexcept
745745 auto biased_exp {static_cast <int >(exp + detail::bias_v<decimal128_t >)};
746746 BOOST_DECIMAL_IF_CONSTEXPR (sizeof (T1) >= sizeof (significand_type))
747747 {
748- if (coeff > detail::d128_max_significand_value || biased_exp < 0 )
748+ if (coeff > detail::d128_max_significand_value || biased_exp < -(detail::precision_v< decimal128_t > - 1 ) )
749749 {
750750 coeff_digits = detail::coefficient_rounding<decimal128_t >(coeff, exp, biased_exp, sign, detail::num_digits (coeff));
751751 }
@@ -788,6 +788,19 @@ constexpr decimal128_t::decimal128_t(T1 coeff, T2 exp, bool sign) noexcept
788788 reduced_coeff *= detail::pow10 (static_cast <significand_type>(digit_delta));
789789 *this = decimal128_t (reduced_coeff, exp, sign);
790790 }
791+ else if (coeff_digits + biased_exp <= detail::precision_v<decimal128_t >)
792+ {
793+ // Handle the case of sub-normals that don't need further rounding
794+ bits_.high = sign ? detail::d128_sign_mask : UINT64_C (0 ); // Reset the sign bit
795+ const auto zeros {detail::remove_trailing_zeros (reduced_coeff)};
796+ biased_exp += zeros.number_of_removed_zeros ;
797+ reduced_coeff = zeros.trimmed_number ;
798+ if (biased_exp > 0 )
799+ {
800+ reduced_coeff *= detail::pow10 (static_cast <significand_type>(biased_exp));
801+ }
802+ bits_ |= reduced_coeff;
803+ }
791804 else if (digit_delta < 0 && coeff_digits - digit_delta <= detail::precision_v<decimal128_t >)
792805 {
793806 const auto offset {detail::precision_v<decimal128_t > - coeff_digits};
0 commit comments