Skip to content

Start building wrapper of GCC decimal32 #823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 56 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
d9c93dd
Add definition of [[nodiscard]]
mborland Jan 23, 2025
379786d
Add framework and accessors of a gcc_decimal32 wrapper
mborland Jan 23, 2025
487fe5b
Add construction from and conversion to integers
mborland Jan 23, 2025
88f78ac
Add conversion to float
mborland Jan 23, 2025
2642c25
Add return type and underlying member function
mborland Jan 23, 2025
51d87fe
Add Unary operators
mborland Jan 23, 2025
3780bd4
Add binary operators
mborland Jan 23, 2025
f13cfb6
Add static assert
mborland Jan 23, 2025
58db909
Fix formatting and add 0 case
mborland Jan 23, 2025
65474b0
Use auto with concept / trailing return
mborland Jan 24, 2025
43b9120
Remove no discard as it breaks old compilers
mborland Jan 24, 2025
33ea12d
Add comparison operators
mborland Jan 24, 2025
ecc41c8
Add same type operators
mborland Jan 24, 2025
ca05e9b
Add combined accessor
mborland Jan 24, 2025
951c5ac
Allow accessors to be public for debugging
mborland Jan 24, 2025
d540f85
Allow accessor access
mborland Jan 24, 2025
f6263ba
Add test of encoding / decoding vs decimal32
mborland Jan 24, 2025
4d5d9c6
Reverse engineer GCC/IBM type
mborland Jan 24, 2025
038f592
Add 1 shot decode function for decimal32
mborland Jan 24, 2025
eb2e3ed
Fix bias
mborland Jan 24, 2025
e6844be
Add testing of 1 shot decoding
mborland Jan 24, 2025
6e758d5
Put hot branch first
mborland Jan 24, 2025
d482d32
Fix sign conversion
mborland Jan 24, 2025
e38ecd0
Change header guards for non-GCC platforms
mborland Jan 27, 2025
a399b8d
Separate constructors to reduce ambiguity
mborland Jan 27, 2025
4d3e8a2
Fix operators and add basic IO stream
mborland Jan 27, 2025
53cbadc
Add tests
mborland Jan 27, 2025
8e97ac1
Add cmath function framework
mborland Jan 28, 2025
2f468e8
Move check for libstdc++ decimal
mborland Jan 28, 2025
1276154
Add wrapper overload to internal type traits
mborland Jan 28, 2025
c0a8f85
Add new class to forward if applicable
mborland Jan 28, 2025
a33cb3e
Wrapper types are not constexpr constructible
mborland Jan 28, 2025
a7445e6
Add support of to integral method
mborland Jan 28, 2025
85560e5
Add additional integer conversion functions
mborland Jan 28, 2025
d8630f5
Add the spaceship operator
mborland Jan 28, 2025
99d8392
Re-enable all testing
mborland Jan 28, 2025
2f1ed0d
Fix tests for non-GCC toolchains
mborland Jan 28, 2025
f3afb3f
Configure using GCC internal macro
mborland Jan 28, 2025
3e1af4b
Add big endian bit masks
mborland Jan 28, 2025
106c6bf
Include GCC compiler check too
mborland Jan 28, 2025
18d4ed1
Add increment and decrement operators
mborland Jan 28, 2025
87400fa
Make return types consistent
mborland Jan 28, 2025
0dd23e7
Add compound assignment
mborland Jan 28, 2025
9c3ec0f
Update basic compile test
mborland Jan 28, 2025
47b37ee
Add testing of basic mathematical operators
mborland Jan 28, 2025
fdd011b
Add non-finite values testing and generation
mborland Jan 28, 2025
e5795e0
Extract values of non-finites
mborland Jan 28, 2025
467644e
Add support for std::numeric_limits<gcc_decimal32>
mborland Jan 28, 2025
bd3b001
Ignore class mem-access warning
mborland Jan 29, 2025
0b97aba
Remove workaround ostream operator
mborland Jan 29, 2025
ab6b512
Add frexp10 friend
mborland Jan 29, 2025
1912f74
Replace constexpr variables with const since no constexpr constructor
mborland Jan 29, 2025
7301baf
Add proper decimal iostream header
mborland Jan 29, 2025
c843dd7
Add LCOV exclusions
mborland Jan 29, 2025
482ece7
Suppress / fix additional test only warnings
mborland Jan 29, 2025
d123e59
Disable on big endian arch
mborland Feb 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions include/boost/decimal/charconv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -780,11 +780,11 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_impl(char* first, char* last, TargetDecima
}

auto abs_value = abs(value);
constexpr auto max_fractional_value = impl::decimal_val_v<TargetDecimalType> < 64 ? TargetDecimalType{1, 7} :
impl::decimal_val_v<TargetDecimalType> < 128 ? TargetDecimalType{1, 16} :
TargetDecimalType{1, 34};
const auto max_fractional_value = impl::decimal_val_v<TargetDecimalType> < 64 ? TargetDecimalType{1, 7} :
impl::decimal_val_v<TargetDecimalType> < 128 ? TargetDecimalType{1, 16} :
TargetDecimalType{1, 34};

constexpr auto min_fractional_value = TargetDecimalType{1, -4};
const auto min_fractional_value = TargetDecimalType{1, -4};

// Unspecified precision so we always go with the shortest representation
if (precision == -1)
Expand Down
63 changes: 58 additions & 5 deletions include/boost/decimal/decimal32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ BOOST_DECIMAL_EXPORT class decimal32 final // NOLINT(cppcoreguidelines-special-m

std::uint32_t bits_ {};

#ifdef BOOST_DECIMAL_DEBUG_ACCESSORS
public:
#endif
// Returns the un-biased (quantum) exponent
constexpr auto unbiased_exponent() const noexcept -> exponent_type ;

Expand All @@ -153,6 +156,12 @@ BOOST_DECIMAL_EXPORT class decimal32 final // NOLINT(cppcoreguidelines-special-m
constexpr auto full_significand() const noexcept -> significand_type ;
constexpr auto isneg() const noexcept -> bool;

// Returns a complete struct so we don't have to decode multiple times
constexpr auto to_components() const noexcept -> detail::decimal32_components;

#ifdef BOOST_DECIMAL_DEBUG_ACCESSORS
private:
#endif
// Attempts conversion to integral type:
// If this is nan sets errno to EINVAL and returns 0
// If this is not representable sets errno to ERANGE and returns 0
Expand Down Expand Up @@ -1444,18 +1453,62 @@ constexpr auto decimal32::full_significand() const noexcept -> significand_type
return significand;
}

constexpr auto decimal32::isneg() const noexcept -> bool
{
return static_cast<bool>(bits_ & detail::d32_sign_mask);
}

constexpr auto decimal32::to_components() const noexcept -> detail::decimal32_components
{
detail::decimal32_components components {};

exponent_type expval {};
significand_type significand {};

const auto comb_bits {(bits_ & detail::d32_comb_11_mask)};

switch (comb_bits)
{
case detail::d32_comb_11_mask:
// bits 2 and 3 are the exp part of the combination field
expval = (bits_ & detail::d32_comb_11_exp_bits) >> (detail::d32_significand_bits + 1);
// Only need the one bit of T because the other 3 are implied
significand = (bits_ & detail::d32_comb_11_significand_bits) == detail::d32_comb_11_significand_bits ?
UINT32_C(0b1001'0000000000'0000000000) :
UINT32_C(0b1000'0000000000'0000000000);
break;
case detail::d32_comb_10_mask:
expval = UINT32_C(0b10000000);
// Last three bits in the combination field, so we need to shift past the exp field
// which is next
significand |= (bits_ & detail::d32_comb_00_01_10_significand_bits) >> detail::d32_exponent_bits;
break;
case detail::d32_comb_01_mask:
expval = UINT32_C(0b01000000);
significand |= (bits_ & detail::d32_comb_00_01_10_significand_bits) >> detail::d32_exponent_bits;
break;
case 0U:
significand |= (bits_ & detail::d32_comb_00_01_10_significand_bits) >> detail::d32_exponent_bits;
break;
}

significand |= (bits_ & detail::d32_significand_mask);
expval |= (bits_ & detail::d32_exponent_mask) >> detail::d32_significand_bits;

components.sig = significand;
components.exp = static_cast<decimal32::biased_exponent_type>(expval) - detail::bias_v<decimal32>;
components.sign = bits_ & detail::d32_sign_mask;

return components;
}

template <typename T>
constexpr auto decimal32::edit_significand(T sig) noexcept
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void)
{
*this = decimal32(sig, this->biased_exponent(), this->isneg());
}

constexpr auto decimal32::isneg() const noexcept -> bool
{
return static_cast<bool>(bits_ & detail::d32_sign_mask);
}

// Allows changing the sign even on nans and infs
constexpr auto decimal32::edit_sign(bool sign) noexcept -> void
{
Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/cmath/acosh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ constexpr auto acosh_impl(T x) noexcept
#endif
else
{
constexpr T one { 1, 0 };
const T one { 1, 0 };

if (x < one)
{
Expand Down
4 changes: 2 additions & 2 deletions include/boost/decimal/detail/cmath/asinh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ constexpr auto asinh_impl(T x) noexcept
{
// Use (parts of) the implementation of asinh from Boost.Math.

constexpr T zero { 0, 0 };
constexpr T one { 1, 0 };
const T zero { 0, 0 };
const T one { 1, 0 };

if (x < zero)
{
Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/cmath/atan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ constexpr auto atan_impl(T x) noexcept
#endif
else
{
constexpr T one { 1 };
const T one { 1 };

if (x <= T { 48 })
{
Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/cmath/atan2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ constexpr auto atan2_impl(T y, T x) noexcept
}
else if (fpcx == FP_INFINITE && !signx && isfinitey)
{
constexpr T zero { 0, 0 };
const T zero { 0, 0 };

result = signy ? -zero : zero;
}
Expand Down
4 changes: 2 additions & 2 deletions include/boost/decimal/detail/cmath/atanh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ constexpr auto atanh_impl(T x) noexcept
}
else
{
constexpr T zero { 0, 0 };
const T zero { 0, 0 };

const auto b_neg = x < zero;
const auto xx = abs(x);

constexpr T one { 1, 0 };
const T one { 1, 0 };

if (xx > one)
{
Expand Down
4 changes: 2 additions & 2 deletions include/boost/decimal/detail/cmath/ceil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ constexpr auto ceil BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (T val) noexcept
{
using DivType = typename T::significand_type;

constexpr T zero {0, 0};
constexpr T one {1, 0};
const T zero {0, 0};
const T one {1, 0};
const auto fp {fpclassify(val)};

switch (fp)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/cmath/cos.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ constexpr auto cos_impl(T x) noexcept
}
else
{
constexpr T one { 1 };
const T one { 1 };

result = one;
}
Expand Down
4 changes: 2 additions & 2 deletions include/boost/decimal/detail/cmath/cosh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ constexpr auto cosh_impl(T x) noexcept
{
const auto fpc = fpclassify(x);

constexpr T zero { 0, 0 };
constexpr T one { 1, 0 };
const T zero { 0, 0 };
const T one { 1, 0 };

auto result = zero;

Expand Down
8 changes: 4 additions & 4 deletions include/boost/decimal/detail/cmath/ellint_1.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ template <typename T>
constexpr auto ellint_1_impl(T m, T phi) noexcept
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
{
constexpr T one { 1 };
const T one { 1 };

T result { };

Expand All @@ -47,7 +47,7 @@ constexpr auto ellint_1_impl(T m, T phi) noexcept
}
else if((fpc_phi == FP_ZERO) && (fpc_m == FP_NORMAL))
{
constexpr T zero { 0 };
const T zero { 0 };

result = zero;
}
Expand Down Expand Up @@ -132,7 +132,7 @@ template <typename T>
constexpr auto comp_ellint_1_impl(T m) noexcept
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
{
constexpr T one { 1 };
const T one { 1 };

T result { };

Expand All @@ -152,7 +152,7 @@ constexpr auto comp_ellint_1_impl(T m) noexcept
}
else
{
constexpr T zero { 0 };
const T zero { 0 };

T Fpm { };

Expand Down
8 changes: 4 additions & 4 deletions include/boost/decimal/detail/cmath/ellint_2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ template <typename T>
constexpr auto ellint_2_impl(T m, T phi) noexcept
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
{
constexpr T one { 1 };
const T one { 1 };

T result { };

Expand All @@ -47,7 +47,7 @@ constexpr auto ellint_2_impl(T m, T phi) noexcept
}
else if((fpc_phi == FP_ZERO) && (fpc_m == FP_NORMAL))
{
constexpr T zero { 0 };
const T zero { 0 };

result = zero;
}
Expand Down Expand Up @@ -129,7 +129,7 @@ template <typename T>
constexpr auto comp_ellint_2_impl(T m) noexcept
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
{
constexpr T one { 1 };
const T one { 1 };

T result { };

Expand All @@ -149,7 +149,7 @@ constexpr auto comp_ellint_2_impl(T m) noexcept
}
else
{
constexpr T zero { 0 };
const T zero { 0 };

T Fpm { };
T Km { };
Expand Down
4 changes: 2 additions & 2 deletions include/boost/decimal/detail/cmath/erf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ constexpr auto erf_series_near_zero_sum(const T &x) noexcept -> T
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
constexpr auto erf_calc_impl(T z, bool invert) noexcept -> T
{
constexpr T zero {0, 0};
const T zero {0, 0};

if (z < zero)
{
Expand Down Expand Up @@ -232,7 +232,7 @@ constexpr auto erf_calc_impl(T z, bool invert) noexcept -> T
T{UINT64_C(8978713707780316114), -22}
};

constexpr T one_and_half {15, -1};
const T one_and_half {15, -1};
result = Y + tools::evaluate_polynomial(P, T(z - one_and_half)) / tools::evaluate_polynomial(Q, T(z - one_and_half));
}
else if (z < T{45, -1})
Expand Down
4 changes: 2 additions & 2 deletions include/boost/decimal/detail/cmath/exp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ constexpr auto exp_impl(T x) noexcept
{
const auto fpc = fpclassify(x);

constexpr T zero { 0, 0 };
constexpr T one { 1, 0 };
const T zero { 0, 0 };
const T one { 1, 0 };

auto result = zero;

Expand Down
4 changes: 2 additions & 2 deletions include/boost/decimal/detail/cmath/expm1.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ constexpr auto expm1_impl(T x) noexcept
{
const auto fpc = fpclassify(x);

constexpr T zero { 0, 0 };
constexpr T one { 1, 0 };
const T zero { 0, 0 };
const T one { 1, 0 };

auto result = zero;

Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/cmath/fdim.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ BOOST_DECIMAL_EXPORT template <typename T>
constexpr auto fdim(T x, T y) noexcept
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
{
constexpr T zero {0, 0};
const T zero {0, 0};

#ifndef BOOST_DECIMAL_FAST_MATH
if (isnan(x) || isinf(x))
Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/cmath/floor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ constexpr auto floor BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (T val) noexcept
{
using DivType = typename T::significand_type;

constexpr T zero {0, 0};
const T zero {0, 0};
constexpr T neg_one {1, 0, true};
const auto fp {fpclassify(val)};

Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/cmath/fpclassify.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ BOOST_DECIMAL_EXPORT template <typename T>
constexpr auto fpclassify BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (T rhs) noexcept
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int)
{
constexpr T zero {0, 0};
const T zero {0, 0};

#ifdef BOOST_DECIMAL_FAST_MATH

Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/cmath/frexp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ constexpr auto frexp_impl(T v, int* expon) noexcept
{
// This implementation of frexp follows closely that of eval_frexp
// in Boost.Multiprecision's cpp_dec_float template class.
constexpr T zero { 0, 0 };
const T zero { 0, 0 };

auto result_frexp = zero;

Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/cmath/frexp10.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace decimal {
BOOST_DECIMAL_EXPORT template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type
{
constexpr T zero {0, 0};
const T zero {0, 0};

if (num == zero)
{
Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/cmath/hypot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace detail {
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
constexpr auto hypot_impl(T x, T y) noexcept
{
constexpr T zero {0, 0};
const T zero {0, 0};

if (abs(x) == zero
#ifndef BOOST_DECIMAL_FAST_MATH
Expand Down
4 changes: 2 additions & 2 deletions include/boost/decimal/detail/cmath/impl/ellint_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ constexpr auto agm(T phi,

const bool phi_is_pi_half { phi == my_pi_half };

constexpr T one { 1 };
const T one { 1 };

const bool has_e { ((pEm != nullptr) || (pEpm != nullptr)) };

Expand All @@ -94,7 +94,7 @@ constexpr auto agm(T phi,
}
else
{
constexpr T zero { 0 };
const T zero { 0 };
constexpr T half { 5 , -1 };

T a0 { one };
Expand Down
4 changes: 2 additions & 2 deletions include/boost/decimal/detail/cmath/impl/pow_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ constexpr auto pow_n_impl(T b, UnsignedIntegralType p) noexcept -> std::enable_i
{
using local_unsigned_integral_type = UnsignedIntegralType;

constexpr T one { 1, 0 };
const T one { 1, 0 };

T result { };

Expand Down Expand Up @@ -78,7 +78,7 @@ constexpr auto pow_n_impl(T b, UnsignedIntegralType p) noexcept -> std::enable_i
template<typename T>
constexpr auto pow_2_impl(int e2) noexcept -> std::enable_if_t<detail::is_decimal_floating_point_v<T>, T>
{
constexpr T one { 1, 0 };
const T one { 1, 0 };

T result { };

Expand Down
Loading
Loading