Further simplify constexpr-ness

This commit is contained in:
ckormanyos
2025-09-03 19:37:37 +02:00
parent 8f536de808
commit 6330e23478
3 changed files with 29 additions and 58 deletions

View File

@@ -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
{

View File

@@ -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));
}
}
}

View File

@@ -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