Skip to content

Commit 0b419f3

Browse files
committed
Fix the generation of subnormal values
1 parent 5af972b commit 0b419f3

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

include/boost/decimal/decimal32_t.hpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ constexpr decimal32_t::decimal32_t(T1 coeff, T2 exp, bool sign) noexcept // NOLI
653653
// Only count the number of digits if we absolutely have to
654654
int coeff_digits {-1};
655655
auto biased_exp {static_cast<int>(exp + detail::bias)};
656-
if (coeff > detail::d32_max_significand_value || biased_exp < 0)
656+
if (coeff > detail::d32_max_significand_value || biased_exp < -(detail::precision_v<decimal32_t> - 1))
657657
{
658658
coeff_digits = detail::coefficient_rounding<decimal32_t>(coeff, exp, biased_exp, sign, detail::num_digits(coeff));
659659
}
@@ -710,6 +710,19 @@ constexpr decimal32_t::decimal32_t(T1 coeff, T2 exp, bool sign) noexcept // NOLI
710710
reduced_coeff *= detail::pow10(static_cast<significand_type>(digit_delta));
711711
*this = decimal32_t(reduced_coeff, exp, sign);
712712
}
713+
else if (coeff_digits + biased_exp <= detail::precision)
714+
{
715+
// Handle the case of sub-normals that don't need further rounding
716+
bits_ = sign ? detail::d32_sign_mask : UINT32_C(0); // Reset the sign bit
717+
const auto zeros {detail::remove_trailing_zeros(reduced_coeff)};
718+
biased_exp += zeros.number_of_removed_zeros;
719+
reduced_coeff = zeros.trimmed_number;
720+
if (biased_exp > 0)
721+
{
722+
reduced_coeff *= detail::pow10(static_cast<significand_type>(biased_exp));
723+
}
724+
bits_ |= reduced_coeff;
725+
}
713726
else if (digit_delta < 0 && coeff_digits - digit_delta <= detail::precision)
714727
{
715728
// We can expand the coefficient to use the maximum number of digits

0 commit comments

Comments
 (0)