Skip to content
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

Start building wrapper of GCC decimal32 #823

Open
wants to merge 23 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
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 @@ -1440,18 +1449,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
6 changes: 6 additions & 0 deletions include/boost/decimal/detail/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,12 @@ typedef unsigned __int128 uint128_t;
# endif
# endif

#ifdef __has_cpp_attribute
# if __has_cpp_attribute(nodiscard)
# define BOOST_DECIMAL_NO_DISCARD [[nodiscard]]
# endif
#endif

#endif

// Since we should not be able to pull these in from the STL in module mode define them ourselves
Expand Down
Loading
Loading