Skip to content

Commit fcc8a2e

Browse files
committed
Merge branch 'develop' into 1137
2 parents ff3dedb + ce72068 commit fcc8a2e

File tree

15 files changed

+123
-47
lines changed

15 files changed

+123
-47
lines changed

doc/modules/ROOT/pages/basics.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Every decimal type can be constructed in a few ways:
1717
[source, c++]
1818
----
1919
template <typename UnsignedInteger, typename Integer>
20-
constexpr decimal32_t(UnsignedInteger coefficient, Integer exponent, bool sign = false) noexcept;
20+
constexpr decimal32_t(UnsignedInteger coefficient, Integer exponent, bool is_negative = false) noexcept;
2121
2222
template <typename SignedInteger, typename Integer>
2323
constexpr decimal32_t(SignedInteger coefficient, Integer exponent) noexcept;

doc/modules/ROOT/pages/decimal128_t.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ explicit constexpr decimal128_t(std::string_view str);
6464
#endif
6565
6666
template <typename UnsignedIntegral, typename Integral>
67-
constexpr decimal128_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept;
67+
constexpr decimal128_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept;
6868
6969
template <typename SignedIntegral, typename Integral>
70-
constexpr decimal128_t(SignedIntegral coeff, Integral exp, bool sign = false) noexcept;
70+
constexpr decimal128_t(SignedIntegral coeff, Integral exp, bool is_negative = false) noexcept;
7171
7272
template <typename Integral>
7373
constexpr decimal128_t& operator=(const Integeral& RHS) noexcept;

doc/modules/ROOT/pages/decimal32_t.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ explicit constexpr decimal32_t(std::string_view str);
6464
#endif
6565
6666
template <typename UnsignedIntegral, typename Integral>
67-
constexpr decimal32_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept;
67+
constexpr decimal32_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept;
6868
6969
template <typename SignedIntegral, typename Integral>
7070
constexpr decimal32_t(SignedIntegral coeff, Integral exp) noexcept;

doc/modules/ROOT/pages/decimal64_t.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ explicit constexpr decimal64_t(std::string_view str);
6464
#endif
6565
6666
template <typename UnsignedIntegral, typename Integral>
67-
constexpr decimal64_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept;
67+
constexpr decimal64_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept;
6868
6969
template <typename SignedIntegral, typename Integral>
7070
constexpr decimal64_t(SignedIntegral coeff, Integral exp) noexcept;

doc/modules/ROOT/pages/decimal_fast128_t.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ explicit constexpr decimal_fast128_t(std::string_view str);
6666
#endif
6767
6868
template <typename UnsignedIntegral, typename Integral>
69-
constexpr decimal_fast128_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept;
69+
constexpr decimal_fast128_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept;
7070
7171
template <typename SignedIntegral, typename Integral>
7272
constexpr decimal_fast128_t(SignedIntegral coeff, Integral exp) noexcept;

doc/modules/ROOT/pages/decimal_fast32_t.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ explicit constexpr decimal_fast32_t(std::string_view str);
6666
#endif
6767
6868
template <typename UnsignedIntegral, typename Integral>
69-
constexpr decimal_fast32_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept;
69+
constexpr decimal_fast32_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept;
7070
7171
template <typename SignedIntegral, typename Integral>
7272
constexpr decimal_fast32_t(SignedIntegral coeff, Integral exp) noexcept;

doc/modules/ROOT/pages/decimal_fast64_t.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ explicit constexpr decimal_fast64_t(std::string_view str);
6666
#endif
6767
6868
template <typename UnsignedIntegral, typename Integral>
69-
constexpr decimal_fast64_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept;
69+
constexpr decimal_fast64_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept;
7070
7171
template <typename SignedIntegral, typename Integral>
7272
constexpr decimal_fast64_t(SignedIntegral coeff, Integral exp) noexcept;

include/boost/decimal/decimal128_t.hpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ BOOST_DECIMAL_EXPORT class decimal128_t final
262262
#else
263263
template <typename T1, typename T2, std::enable_if_t<detail::is_unsigned_v<T1> && detail::is_integral_v<T2>, bool> = true>
264264
#endif
265-
constexpr decimal128_t(T1 coeff, T2 exp, bool sign = false) noexcept;
265+
constexpr decimal128_t(T1 coeff, T2 exp, bool is_negative = false) noexcept;
266266

267267
#ifdef BOOST_DECIMAL_HAS_CONCEPTS
268268
template <BOOST_DECIMAL_SIGNED_INTEGRAL T1, BOOST_DECIMAL_INTEGRAL T2>
@@ -733,9 +733,9 @@ template <BOOST_DECIMAL_UNSIGNED_INTEGRAL T1, BOOST_DECIMAL_INTEGRAL T2>
733733
#else
734734
template <typename T1, typename T2, std::enable_if_t<detail::is_unsigned_v<T1> && detail::is_integral_v<T2>, bool>>
735735
#endif
736-
constexpr decimal128_t::decimal128_t(T1 coeff, T2 exp, bool sign) noexcept
736+
constexpr decimal128_t::decimal128_t(T1 coeff, T2 exp, bool is_negative) noexcept
737737
{
738-
bits_.high = sign ? detail::d128_sign_mask : UINT64_C(0);
738+
bits_.high = is_negative ? detail::d128_sign_mask : UINT64_C(0);
739739

740740
// If the coeff is not in range make it so
741741
// The coefficient needs at least 110 bits so there's a good chance we don't need to
@@ -745,9 +745,9 @@ 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
{
750-
coeff_digits = detail::coefficient_rounding<decimal128_t>(coeff, exp, biased_exp, sign, detail::num_digits(coeff));
750+
coeff_digits = detail::coefficient_rounding<decimal128_t>(coeff, exp, biased_exp, is_negative, detail::num_digits(coeff));
751751
}
752752
}
753753

@@ -786,19 +786,32 @@ constexpr decimal128_t::decimal128_t(T1 coeff, T2 exp, bool sign) noexcept
786786
{
787787
exp -= digit_delta;
788788
reduced_coeff *= detail::pow10(static_cast<significand_type>(digit_delta));
789-
*this = decimal128_t(reduced_coeff, exp, sign);
789+
*this = decimal128_t(reduced_coeff, exp, is_negative);
790+
}
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 += static_cast<int>(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;
790803
}
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};
794807
exp -= offset;
795808
reduced_coeff *= detail::pow10(static_cast<significand_type>(offset));
796-
*this = decimal128_t(reduced_coeff, exp, sign);
809+
*this = decimal128_t(reduced_coeff, exp, is_negative);
797810
}
798811
else
799812
{
800813
bits_ = exp < 0 ? zero : detail::d128_inf_mask;
801-
bits_.high |= sign ? detail::d128_sign_mask : UINT64_C(0);
814+
bits_.high |= is_negative ? detail::d128_sign_mask : UINT64_C(0);
802815
}
803816
}
804817
}

include/boost/decimal/decimal32_t.hpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ BOOST_DECIMAL_EXPORT class decimal32_t final // NOLINT(cppcoreguidelines-special
288288
#else
289289
template <typename T1, typename T2, std::enable_if_t<detail::is_unsigned_v<T1> && detail::is_integral_v<T2>, bool> = true>
290290
#endif
291-
constexpr decimal32_t(T1 coeff, T2 exp, bool sign = false) noexcept;
291+
constexpr decimal32_t(T1 coeff, T2 exp, bool is_negative = false) noexcept;
292292

293293
#ifdef BOOST_DECIMAL_HAS_CONCEPTS
294294
template <BOOST_DECIMAL_SIGNED_INTEGRAL T1, BOOST_DECIMAL_INTEGRAL T2>
@@ -642,20 +642,20 @@ template <BOOST_DECIMAL_UNSIGNED_INTEGRAL T1, BOOST_DECIMAL_INTEGRAL T2>
642642
#else
643643
template <typename T1, typename T2, std::enable_if_t<detail::is_unsigned_v<T1> && detail::is_integral_v<T2>, bool>>
644644
#endif
645-
constexpr decimal32_t::decimal32_t(T1 coeff, T2 exp, bool sign) noexcept // NOLINT(readability-function-cognitive-complexity,misc-no-recursion)
645+
constexpr decimal32_t::decimal32_t(T1 coeff, T2 exp, bool is_negative) noexcept // NOLINT(readability-function-cognitive-complexity,misc-no-recursion)
646646
{
647647
static_assert(detail::is_integral_v<T1>, "Coefficient must be an integer");
648648
static_assert(detail::is_integral_v<T2>, "Exponent must be an integer");
649649

650-
bits_ = sign ? detail::d32_sign_mask : UINT32_C(0);
650+
bits_ = is_negative ? detail::d32_sign_mask : UINT32_C(0);
651651

652652
// If the coeff is not in range, make it so
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
{
658-
coeff_digits = detail::coefficient_rounding<decimal32_t>(coeff, exp, biased_exp, sign, detail::num_digits(coeff));
658+
coeff_digits = detail::coefficient_rounding<decimal32_t>(coeff, exp, biased_exp, is_negative, detail::num_digits(coeff));
659659
}
660660

661661
auto reduced_coeff {static_cast<significand_type>(coeff)};
@@ -708,21 +708,34 @@ constexpr decimal32_t::decimal32_t(T1 coeff, T2 exp, bool sign) noexcept // NOLI
708708
{
709709
exp -= digit_delta;
710710
reduced_coeff *= detail::pow10(static_cast<significand_type>(digit_delta));
711-
*this = decimal32_t(reduced_coeff, exp, sign);
711+
*this = decimal32_t(reduced_coeff, exp, is_negative);
712+
}
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 += static_cast<int>(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;
712725
}
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
716729
const auto offset {detail::precision - coeff_digits};
717730
exp -= offset;
718731
reduced_coeff *= detail::pow10(static_cast<significand_type>(offset));
719-
*this = decimal32_t(reduced_coeff, exp, sign);
732+
*this = decimal32_t(reduced_coeff, exp, is_negative);
720733
}
721734
else
722735
{
723736
// Reset the value and make sure to preserve the sign of 0/inf
724737
bits_ = exp < 0 ? UINT32_C(0) : detail::d32_inf_mask;
725-
bits_ |= sign ? detail::d32_sign_mask : UINT32_C(0);
738+
bits_ |= is_negative ? detail::d32_sign_mask : UINT32_C(0);
726739
}
727740
}
728741
}

include/boost/decimal/decimal64_t.hpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ BOOST_DECIMAL_EXPORT class decimal64_t final
325325
#else
326326
template <typename T1, typename T2, std::enable_if_t<detail::is_unsigned_v<T1> && detail::is_integral_v<T2>, bool> = true>
327327
#endif
328-
constexpr decimal64_t(T1 coeff, T2 exp, bool sign = false) noexcept;
328+
constexpr decimal64_t(T1 coeff, T2 exp, bool is_negative = false) noexcept;
329329

330330
#ifdef BOOST_DECIMAL_HAS_CONCEPTS
331331
template <BOOST_DECIMAL_SIGNED_INTEGRAL T1, BOOST_DECIMAL_INTEGRAL T2>
@@ -640,16 +640,16 @@ template <BOOST_DECIMAL_UNSIGNED_INTEGRAL T1, BOOST_DECIMAL_INTEGRAL T2>
640640
#else
641641
template <typename T1, typename T2, std::enable_if_t<detail::is_unsigned_v<T1> && detail::is_integral_v<T2>, bool>>
642642
#endif
643-
constexpr decimal64_t::decimal64_t(T1 coeff, T2 exp, bool sign) noexcept
643+
constexpr decimal64_t::decimal64_t(T1 coeff, T2 exp, bool is_negative) noexcept
644644
{
645-
bits_ = sign ? detail::d64_sign_mask : UINT64_C(0);
645+
bits_ = is_negative ? detail::d64_sign_mask : UINT64_C(0);
646646

647647
// If the coeff is not in range, make it so
648648
int coeff_digits {-1};
649649
auto biased_exp {static_cast<int>(exp) + detail::bias_v<decimal64_t>};
650-
if (coeff > detail::d64_max_significand_value || biased_exp < 0)
650+
if (coeff > detail::d64_max_significand_value || biased_exp < -(detail::precision_v<decimal64_t> - 1))
651651
{
652-
coeff_digits = detail::coefficient_rounding<decimal64_t>(coeff, exp, biased_exp, sign, detail::num_digits(coeff));
652+
coeff_digits = detail::coefficient_rounding<decimal64_t>(coeff, exp, biased_exp, is_negative, detail::num_digits(coeff));
653653
}
654654

655655
auto reduced_coeff {static_cast<significand_type>(coeff)};
@@ -702,20 +702,33 @@ constexpr decimal64_t::decimal64_t(T1 coeff, T2 exp, bool sign) noexcept
702702
{
703703
exp -= digit_delta;
704704
reduced_coeff *= detail::pow10(static_cast<significand_type>(digit_delta));
705-
*this = decimal64_t(reduced_coeff, exp, sign);
705+
*this = decimal64_t(reduced_coeff, exp, is_negative);
706+
}
707+
else if (coeff_digits + biased_exp <= detail::precision_v<decimal64_t>)
708+
{
709+
// Handle the case of sub-normals that don't need further rounding
710+
bits_ = sign ? detail::d64_sign_mask : UINT64_C(0); // Reset the sign bit
711+
const auto zeros {detail::remove_trailing_zeros(reduced_coeff)};
712+
biased_exp += static_cast<int>(zeros.number_of_removed_zeros);
713+
reduced_coeff = zeros.trimmed_number;
714+
if (biased_exp > 0)
715+
{
716+
reduced_coeff *= detail::pow10(static_cast<significand_type>(biased_exp));
717+
}
718+
bits_ |= reduced_coeff;
706719
}
707720
else if (digit_delta < 0 && coeff_digits - digit_delta <= detail::precision_v<decimal64_t>)
708721
{
709722
const auto offset {detail::precision_v<decimal64_t> - coeff_digits};
710723
exp -= offset;
711724
reduced_coeff *= detail::pow10(static_cast<significand_type>(offset));
712-
*this = decimal64_t(reduced_coeff, exp, sign);
725+
*this = decimal64_t(reduced_coeff, exp, is_negative);
713726
}
714727
else
715728
{
716729
// Reset the value and make sure to preserve the sign of 0/inf
717730
bits_ = exp < 0 ? UINT64_C(0) : detail::d64_inf_mask;
718-
bits_ |= sign ? detail::d64_sign_mask : UINT64_C(0);
731+
bits_ |= is_negative ? detail::d64_sign_mask : UINT64_C(0);
719732
}
720733
}
721734
}

0 commit comments

Comments
 (0)