diff --git a/doc/decimal/decimal128.adoc b/doc/decimal/decimal128.adoc index a6b2c3d20..8a5dd713c 100644 --- a/doc/decimal/decimal128.adoc +++ b/doc/decimal/decimal128.adoc @@ -30,6 +30,11 @@ namespace decimal { class decimal128 { +public: + using significand_type = detail::uint128; + using exponent_type = std::uint32_t; + using biased_exponent_type = std::int32_t; + // Paragraph numbers are from ISO/IEC DTR 24733 // 3.2.4.1 construct/copy/destroy diff --git a/doc/decimal/decimal128_fast.adoc b/doc/decimal/decimal128_fast.adoc index 0c39b529c..860105e4c 100644 --- a/doc/decimal/decimal128_fast.adoc +++ b/doc/decimal/decimal128_fast.adoc @@ -30,6 +30,11 @@ namespace decimal { class decimal128_fast { +public: + using significand_type = detail::uint128; + using exponent_type = std::uint32_t; + using biased_exponent_type = std::int32_t; + // Paragraph numbers are from ISO/IEC DTR 24733 // 3.2.4.1 construct/copy/destroy diff --git a/doc/decimal/decimal32.adoc b/doc/decimal/decimal32.adoc index 2fd48eac4..d65ba1854 100644 --- a/doc/decimal/decimal32.adoc +++ b/doc/decimal/decimal32.adoc @@ -30,6 +30,11 @@ namespace decimal { class decimal32 { +public: + using significand_type = std::uint32_t; + using exponent_type = std::uint32_t; + using biased_exponent_type = std::int32_t; + // Paragraph numbers are from ISO/IEC DTR 24733 // 3.2.2.1 construct/copy/destroy diff --git a/doc/decimal/decimal32_fast.adoc b/doc/decimal/decimal32_fast.adoc index 307c9e81d..3649e6cbe 100644 --- a/doc/decimal/decimal32_fast.adoc +++ b/doc/decimal/decimal32_fast.adoc @@ -14,7 +14,7 @@ https://www.boost.org/LICENSE_1_0.txt The performance changes by being non-IEEE 754 compliant so that the value does not have to be decoded from bits, but is instead directly represented internal to the type. As is often the case this trades space for time by having greater storage width requirements. -- Storage width - At least 48bits (`std::uint_fast32_t` + `std::uint_fast8_t` + `bool`) +- Storage width - 48bits (`std::uint32_t` + `std::uint8_t` + `bool`) - Precision - 7 decimal digits (not bits like binary) - Max exponent - 96 - Max Value - 9.999999e96 @@ -30,6 +30,11 @@ namespace decimal { class decimal32_fast { +public: + using significand_type = std::uint32_t; + using exponent_type = std::uint8_t; + using biased_exponent_type = std::int32_t; + // Paragraph numbers are from ISO/IEC DTR 24733 // 3.2.2.1 construct/copy/destroy diff --git a/doc/decimal/decimal64.adoc b/doc/decimal/decimal64.adoc index 08dd83f02..c6c18316d 100644 --- a/doc/decimal/decimal64.adoc +++ b/doc/decimal/decimal64.adoc @@ -30,6 +30,11 @@ namespace decimal { class decimal64 { +public: + using significand_type = std::uint64_t; + using exponent_type = std::uint32_t; + using biased_exponent_type = std::int32_t; + // Paragraph numbers are from ISO/IEC DTR 24733 // 3.2.3.1 construct/copy/destroy diff --git a/doc/decimal/decimal64_fast.adoc b/doc/decimal/decimal64_fast.adoc index 417a22ad4..9393f2b98 100644 --- a/doc/decimal/decimal64_fast.adoc +++ b/doc/decimal/decimal64_fast.adoc @@ -14,7 +14,7 @@ https://www.boost.org/LICENSE_1_0.txt The performance changes by being non-IEEE 754 compliant so that the value does not have to be decoded from bits, but is instead directly represented internal to the type. As is often the case this trades space for time by having greater storage width requirements. -- Storage width - At least 88 bits (`std::uint_fast64_t` + `std::uint_fast_16_t` + `bool`) +- Storage width - 88 bits (`std::uint64_t` + `std::uint16_t` + `bool`) - Precision - 16 decimal digits (not bits like binary) - Max exponent - 385 - Max Value - 9.999999999999999e385 @@ -30,6 +30,11 @@ namespace decimal { class decimal64_fast { +public: + using significand_type = std::uint64_t; + using exponent_type = std::uint16_t; + using biased_exponent_type = std::int32_t; + // Paragraph numbers are from ISO/IEC DTR 24733 // 3.2.3.1 construct/copy/destroy diff --git a/include/boost/decimal/decimal128.hpp b/include/boost/decimal/decimal128.hpp index 669020b8d..280042268 100644 --- a/include/boost/decimal/decimal128.hpp +++ b/include/boost/decimal/decimal128.hpp @@ -155,7 +155,7 @@ BOOST_DECIMAL_EXPORT class decimal128 final { public: using significand_type = detail::uint128; - using exponent_type = std::uint64_t; + using exponent_type = std::uint32_t; using biased_exponent_type = std::int32_t; private: diff --git a/include/boost/decimal/decimal128_fast.hpp b/include/boost/decimal/decimal128_fast.hpp index 520c53ac0..3d89f3a47 100644 --- a/include/boost/decimal/decimal128_fast.hpp +++ b/include/boost/decimal/decimal128_fast.hpp @@ -41,7 +41,7 @@ BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d128_fast_snan_high_bits = UINT64_MAX; struct decimal128_fast_components { using significand_type = uint128; - using biased_exponent_type = std::int_fast32_t; + using biased_exponent_type = std::int32_t; significand_type sig; biased_exponent_type exp; @@ -54,8 +54,8 @@ BOOST_DECIMAL_EXPORT class decimal128_fast final { public: using significand_type = detail::uint128; - using exponent_type = std::uint_fast32_t; - using biased_exponent_type = std::int_fast32_t; + using exponent_type = std::uint32_t; + using biased_exponent_type = std::int32_t; private: // Instead of having to encode and decode at every operation diff --git a/include/boost/decimal/decimal32_fast.hpp b/include/boost/decimal/decimal32_fast.hpp index 8e5b2304d..68e6da8d3 100644 --- a/include/boost/decimal/decimal32_fast.hpp +++ b/include/boost/decimal/decimal32_fast.hpp @@ -28,18 +28,18 @@ namespace decimal { namespace detail { -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d32_fast_inf = std::numeric_limits::max() - 3; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d32_fast_qnan = std::numeric_limits::max() - 2; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d32_fast_snan = std::numeric_limits::max() - 1; +BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_fast_inf = std::numeric_limits::max() - 3; +BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_fast_qnan = std::numeric_limits::max() - 2; +BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_fast_snan = std::numeric_limits::max() - 1; } BOOST_DECIMAL_EXPORT class decimal32_fast final { public: - using significand_type = std::uint_fast32_t; - using exponent_type = std::uint_fast8_t; - using biased_exponent_type = std::int_fast32_t; + using significand_type = std::uint32_t; + using exponent_type = std::uint8_t; + using biased_exponent_type = std::int32_t; private: // In regular decimal32 we have to decode the 24 bits of the significand and the 8 bits of the exp @@ -326,7 +326,7 @@ BOOST_DECIMAL_EXPORT class decimal32_fast final template && (detail::impl::decimal_val_v <= detail::impl::decimal_val_v), bool> = true> explicit constexpr operator Decimal() const noexcept; - friend constexpr auto direct_init(std::uint_fast32_t significand, std::uint_fast8_t exponent, bool sign) noexcept -> decimal32_fast; + friend constexpr auto direct_init(significand_type significand, exponent_type exponent, bool sign) noexcept -> decimal32_fast; // or extensions that need to be friends template @@ -379,10 +379,10 @@ constexpr decimal32_fast::decimal32_fast(T1 coeff, T2 exp, bool sign) noexcept exp = 0; } - auto biased_exp {static_cast(exp + detail::bias)}; + auto biased_exp {static_cast(exp + detail::bias)}; // Decimal32 exponent holds 8 bits - if (biased_exp > detail::max_biased_exp_v) + if (biased_exp > detail::max_biased_exp_v || exp > detail::max_biased_exp_v) { significand_ = detail::d32_fast_inf; } @@ -431,7 +431,7 @@ BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_fast::decimal32_fast(Float val) noexcept # pragma GCC diagnostic pop #endif -constexpr auto direct_init(std::uint_fast32_t significand, std::uint_fast8_t exponent, bool sign = false) noexcept -> decimal32_fast +constexpr auto direct_init(decimal32_fast::significand_type significand, decimal32_fast::exponent_type exponent, bool sign = false) noexcept -> decimal32_fast { decimal32_fast val; val.significand_ = significand; @@ -837,9 +837,9 @@ constexpr auto operator+(decimal32_fast lhs, Integer rhs) noexcept exp_type exp_rhs {0}; detail::normalize(sig_rhs, exp_rhs); - const auto final_sig_rhs {static_cast(detail::make_positive_unsigned(sig_rhs))}; + const auto final_sig_rhs {static_cast(detail::make_positive_unsigned(sig_rhs))}; - return detail::d32_add_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_, + return detail::d32_add_impl(static_cast(lhs.significand_), lhs.biased_exponent(), lhs.sign_, final_sig_rhs, exp_rhs, (rhs < 0), abs_lhs_bigger); } @@ -1028,11 +1028,13 @@ constexpr auto div_impl(decimal32_fast lhs, decimal32_fast rhs, decimal32_fast& << "\nexp rhs: " << exp_rhs << std::endl; #endif + using promoted_type = std::uint64_t; + // We promote to uint64 since the significands are currently 32-bits // By appending enough zeros to the LHS we end up finding what we need anyway - constexpr auto ten_pow_precision {detail::pow10(static_cast(detail::precision_v))}; - const auto big_sig_lhs {static_cast(lhs.significand_) * ten_pow_precision}; - const auto res_sig {big_sig_lhs / static_cast(rhs.significand_)}; + constexpr auto ten_pow_precision {detail::pow10(static_cast(detail::precision_v))}; + const auto big_sig_lhs {static_cast(lhs.significand_) * ten_pow_precision}; + const auto res_sig {big_sig_lhs / static_cast(rhs.significand_)}; const auto res_exp {(lhs.biased_exponent() - detail::precision_v) - rhs.biased_exponent()}; q = decimal32_fast(res_sig, res_exp, lhs.sign_ != rhs.sign_); @@ -1500,7 +1502,7 @@ struct numeric_limits static constexpr int min_exponent10 = min_exponent; static constexpr int max_exponent = 96; static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; + static constexpr bool traps = numeric_limits::traps; static constexpr bool tinyness_before = true; // Member functions diff --git a/include/boost/decimal/decimal64.hpp b/include/boost/decimal/decimal64.hpp index 19e089921..0817fef8d 100644 --- a/include/boost/decimal/decimal64.hpp +++ b/include/boost/decimal/decimal64.hpp @@ -142,7 +142,7 @@ BOOST_DECIMAL_EXPORT class decimal64 final { public: using significand_type = std::uint64_t; - using exponent_type = std::uint64_t; + using exponent_type = std::uint32_t; using biased_exponent_type = std::int32_t; private: @@ -1018,7 +1018,7 @@ constexpr auto decimal64::unbiased_exponent() const noexcept -> exponent_type break; } - expval |= (bits_ & detail::d64_exponent_mask) >> detail::d64_significand_bits; + expval |= static_cast((bits_ & detail::d64_exponent_mask) >> detail::d64_significand_bits); return expval; } diff --git a/include/boost/decimal/decimal64_fast.hpp b/include/boost/decimal/decimal64_fast.hpp index ca9cf77ad..ce1b466e3 100644 --- a/include/boost/decimal/decimal64_fast.hpp +++ b/include/boost/decimal/decimal64_fast.hpp @@ -31,14 +31,14 @@ namespace decimal { namespace detail { -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d64_fast_inf = std::numeric_limits::max() - 3; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d64_fast_qnan = std::numeric_limits::max() - 2; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d64_fast_snan = std::numeric_limits::max() - 1; +BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_fast_inf = std::numeric_limits::max() - 3; +BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_fast_qnan = std::numeric_limits::max() - 2; +BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_fast_snan = std::numeric_limits::max() - 1; struct decimal64_fast_components { - using significand_type = std::uint_fast64_t; - using biased_exponent_type = std::int_fast32_t; + using significand_type = std::uint64_t; + using biased_exponent_type = std::int32_t; significand_type sig; biased_exponent_type exp; @@ -50,9 +50,9 @@ struct decimal64_fast_components BOOST_DECIMAL_EXPORT class decimal64_fast final { public: - using significand_type = std::uint_fast64_t; - using exponent_type = std::uint_fast16_t; - using biased_exponent_type = std::int_fast32_t; + using significand_type = std::uint64_t; + using exponent_type = std::uint16_t; + using biased_exponent_type = std::int32_t; private: // In regular decimal64 we have to decode the significand end exponent @@ -390,9 +390,9 @@ constexpr decimal64_fast::decimal64_fast(T1 coeff, T2 exp, bool sign) noexcept exp = 0; } - const auto biased_exp {static_cast(exp + detail::bias_v)}; + const auto biased_exp {static_cast(exp + detail::bias_v)}; - if (biased_exp > detail::max_biased_exp_v) + if (biased_exp > detail::max_biased_exp_v || exp > detail::max_biased_exp_v) { significand_ = detail::d64_fast_inf; } diff --git a/include/boost/decimal/detail/components.hpp b/include/boost/decimal/detail/components.hpp index 5b6738e0f..3766f77d2 100644 --- a/include/boost/decimal/detail/components.hpp +++ b/include/boost/decimal/detail/components.hpp @@ -27,8 +27,8 @@ struct decimal32_components struct decimal32_fast_components { - using significand_type = std::uint_fast32_t; - using biased_exponent_type = std::int_fast32_t; + using significand_type = std::uint32_t; + using biased_exponent_type = std::int32_t; significand_type sig; biased_exponent_type exp; diff --git a/include/boost/decimal/detail/promote_significand.hpp b/include/boost/decimal/detail/promote_significand.hpp index b53149d37..3a0e57f55 100644 --- a/include/boost/decimal/detail/promote_significand.hpp +++ b/include/boost/decimal/detail/promote_significand.hpp @@ -19,7 +19,7 @@ namespace impl { template struct promote_significand { - using type = std::conditional_t::digits10 < std::numeric_limits::digits10, + using type = std::conditional_t>::digits10 < std::numeric_limits::digits10, typename DecimalType::significand_type, detail::make_unsigned_t>; };