mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-01-19 04:22:11 +00:00
Further simplify constexpr-ness
This commit is contained in:
@@ -32,6 +32,23 @@
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail {
|
||||
|
||||
template <typename UnsignedIntegralType,
|
||||
typename FloatType>
|
||||
constexpr auto float_mask() noexcept -> UnsignedIntegralType
|
||||
{
|
||||
using local_unsigned_integral_type = UnsignedIntegralType;
|
||||
using local_float_type = FloatType;
|
||||
|
||||
static_assert(static_cast<int>(sizeof(UnsignedIntegralType) * 8u) > static_cast<int>(cpp_df_qf_detail::ccmath::numeric_limits<local_float_type>::digits),
|
||||
"Error: this function is intended for unsigned integral type wider than the float type.");
|
||||
|
||||
return
|
||||
{
|
||||
local_unsigned_integral_type { local_unsigned_integral_type { 1 } << static_cast<unsigned>(cpp_df_qf_detail::ccmath::numeric_limits<local_float_type>::digits) }
|
||||
- local_unsigned_integral_type { 1 }
|
||||
};
|
||||
}
|
||||
|
||||
template <class FloatingPointTypeA, class FloatingPointTypeB>
|
||||
struct pair
|
||||
{
|
||||
|
||||
@@ -277,67 +277,27 @@ class cpp_double_fp_backend
|
||||
&& boost::multiprecision::detail::is_unsigned<UnsignedIntegralType>::value
|
||||
&& (static_cast<int>(sizeof(UnsignedIntegralType) * 8u) > cpp_df_qf_detail::ccmath::numeric_limits<float_type>::digits))>::type const* = nullptr>
|
||||
constexpr cpp_double_fp_backend(UnsignedIntegralType u)
|
||||
: data(static_cast<float_type>(u & cpp_df_qf_detail::float_mask<UnsignedIntegralType, float_type>()),
|
||||
static_cast<float_type>(0.0F))
|
||||
{
|
||||
using local_unsigned_integral_type = UnsignedIntegralType;
|
||||
|
||||
constexpr local_unsigned_integral_type
|
||||
limb_mask
|
||||
{
|
||||
local_unsigned_integral_type { local_unsigned_integral_type { 1 } << static_cast<unsigned>(cpp_df_qf_detail::ccmath::numeric_limits<float_type>::digits) }
|
||||
- local_unsigned_integral_type { 1 }
|
||||
};
|
||||
|
||||
if (u <= limb_mask)
|
||||
if (u > cpp_df_qf_detail::float_mask<UnsignedIntegralType, float_type>())
|
||||
{
|
||||
data =
|
||||
{
|
||||
static_cast<float_type>(u),
|
||||
static_cast<float_type>(0.0F)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
constexpr local_unsigned_integral_type
|
||||
flt_mask
|
||||
local_unsigned_integral_type
|
||||
local_flt_mask
|
||||
{
|
||||
static_cast<local_unsigned_integral_type>
|
||||
(
|
||||
static_cast<local_unsigned_integral_type>
|
||||
(
|
||||
static_cast<local_unsigned_integral_type>(UINT8_C(1)) << static_cast<unsigned>(cpp_df_qf_detail::ccmath::numeric_limits<float_type>::digits)
|
||||
)
|
||||
- static_cast<local_unsigned_integral_type>(UINT8_C(1))
|
||||
)
|
||||
cpp_df_qf_detail::float_mask<local_unsigned_integral_type, float_type>()
|
||||
};
|
||||
|
||||
data.second = static_cast<float_type>(0.0F);
|
||||
data.first = static_cast<float_type>(u & flt_mask);
|
||||
|
||||
constexpr float_type
|
||||
p2_factor_digits
|
||||
(
|
||||
cpp_df_qf_detail::ccmath::ldexp
|
||||
(
|
||||
static_cast<float_type>(1.0F),
|
||||
cpp_df_qf_detail::ccmath::numeric_limits<float_type>::digits
|
||||
)
|
||||
);
|
||||
|
||||
float_type p2_factor(p2_factor_digits);
|
||||
|
||||
while (u > static_cast<local_unsigned_integral_type>(UINT8_C(0)))
|
||||
for (int index_mask_lsb = cpp_df_qf_detail::ccmath::numeric_limits<float_type>::digits;
|
||||
(index_mask_lsb < static_cast<int>(sizeof(local_unsigned_integral_type) * 8u))
|
||||
&& (local_flt_mask != local_unsigned_integral_type { UINT8_C(0) });
|
||||
index_mask_lsb += cpp_df_qf_detail::ccmath::numeric_limits<float_type>::digits)
|
||||
{
|
||||
u >>= static_cast<unsigned>(cpp_df_qf_detail::ccmath::numeric_limits<float_type>::digits);
|
||||
local_flt_mask <<= static_cast<unsigned>(cpp_df_qf_detail::ccmath::numeric_limits<float_type>::digits);
|
||||
|
||||
const float_type
|
||||
xhi
|
||||
{
|
||||
static_cast<float_type>(static_cast<float_type>(u & flt_mask) * p2_factor)
|
||||
};
|
||||
|
||||
add_unchecked_limb(xhi);
|
||||
|
||||
p2_factor *= p2_factor_digits;
|
||||
add_unchecked_limb(static_cast<float_type>(u & local_flt_mask));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,18 +519,12 @@ int main()
|
||||
#endif
|
||||
#ifdef TEST_CPP_DOUBLE_FLOAT
|
||||
|
||||
// When using very old GCC, categorically disable this test for cpp_double_fp_backend.
|
||||
// Do not attempt, at the moment, to track down the compiler's "internal failure".
|
||||
|
||||
#if (defined(BOOST_GCC) && !defined(BOOST_CLANG) && (BOOST_GCC < 80000))
|
||||
#else
|
||||
test<boost::multiprecision::cpp_double_float>();
|
||||
test<boost::multiprecision::cpp_double_double>();
|
||||
test<boost::multiprecision::cpp_double_long_double>();
|
||||
#if defined(BOOST_MP_CPP_DOUBLE_FP_HAS_FLOAT128)
|
||||
test<boost::multiprecision::cpp_double_float128>();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user