Try handle more double_fp findings

This commit is contained in:
ckormanyos
2025-09-04 11:49:57 +02:00
parent 43ce2d3149
commit 732b19bd2f
4 changed files with 84 additions and 43 deletions
@@ -56,15 +56,20 @@ struct pair
using float_type = FloatingPointTypeA;
#if (defined(BOOST_CXX_VERSION) && (BOOST_CXX_VERSION >= 202002L))
float_type first;
float_type second;
#else
float_type first { };
float_type second { };
#endif
constexpr pair() : first { }, second { } { };
constexpr pair(float_type a, float_type b) : first { a }, second { b } { }
constexpr pair(const pair& other) : first { other.first }, second { other.second } { }
constexpr pair() noexcept { }
constexpr pair(float_type a, float_type b) noexcept : first { a }, second { b } { }
constexpr pair(const pair& other) noexcept : first { other.first }, second { other.second } { }
constexpr pair(pair&& other) noexcept : first { other.first }, second { other.second } { }
constexpr auto operator=(const pair& other) -> pair&
constexpr auto operator=(const pair& other) noexcept -> pair&
{
if (this != &other)
{
@@ -14,7 +14,7 @@
#include <cmath>
#include <type_traits>
#if (defined(__GNUC__) && defined(BOOST_MP_CPP_DOUBLE_FP_HAS_FLOAT128))
#if (defined(BOOST_GCC) && defined(BOOST_MP_CPP_DOUBLE_FP_HAS_FLOAT128))
//
// This is the only way we can avoid
// warning: non-standard suffix on floating constant [-Wpedantic]
+51 -34
View File
@@ -139,7 +139,7 @@ constexpr auto eval_convert_to(OtherFloatingPointType* result, const cpp_double_
// TBD: constexpr on hash_value?
template <typename FloatingPointType>
auto hash_value(const cpp_double_fp_backend<FloatingPointType>& a) -> ::std::size_t;
constexpr auto hash_value(const cpp_double_fp_backend<FloatingPointType>& a) -> ::std::size_t;
template <typename FloatingPointType>
constexpr auto fabs(const cpp_double_fp_backend<FloatingPointType>& a) -> cpp_double_fp_backend<FloatingPointType>;
@@ -385,38 +385,12 @@ class cpp_double_fp_backend
return *this;
}
auto hash() const -> ::std::size_t
constexpr auto hash() const -> ::std::size_t
{
// Hash the raw values of the data field with direct-memory access.
// Use 16-bit (2 byte) chunks as the data size when hashing.
static_assert( ( sizeof(data.first) == sizeof(data.second))
&& ( sizeof(float_type) >= sizeof(std::uint16_t))
&& ((sizeof(float_type) % sizeof(std::uint16_t)) == std::size_t { UINT8_C(0) }),
"Error: float_type size is inappropriate for hashing routine");
auto hash_one
{
[](std::size_t& res, const float_type& val)
{
const std::uint16_t* first { reinterpret_cast<const std::uint16_t*>(&val) };
const std::uint16_t* last { first + std::size_t { sizeof(float_type) / sizeof(std::uint16_t) } };
while (first != last)
{
boost::multiprecision::detail::hash_combine(res, *first);
++first;
}
return res;
}
};
std::size_t result { UINT8_C(0) };
static_cast<void>(hash_one(result, data.first));
static_cast<void>(hash_one(result, data.second));
boost::multiprecision::detail::hash_combine(result, data.first);
boost::multiprecision::detail::hash_combine(result, data.second);
return result;
}
@@ -574,6 +548,21 @@ class cpp_double_fp_backend
data = arithmetic::two_diff(data.first, v.data.first);
if (cpp_df_qf_detail::ccmath::isinf(data.first))
{
// Handle overflow.
const bool b_neg { (data.first < float_type { 0.0F }) };
*this = cpp_double_fp_backend::my_value_inf();
if (b_neg)
{
negate();
}
return *this;
}
data = arithmetic::two_hilo_sum(data.first, data.second + thi_tlo.first);
data = arithmetic::two_hilo_sum(data.first, thi_tlo.second + data.second);
@@ -885,7 +874,7 @@ class cpp_double_fp_backend
}
}
auto str(std::streamsize number_of_digits, const std::ios::fmtflags format_flags) const -> std::string
constexpr auto str(std::streamsize number_of_digits, const std::ios::fmtflags format_flags) const -> std::string
{
if (number_of_digits == 0)
{
@@ -1033,7 +1022,7 @@ class cpp_double_fp_backend
using cpp_bin_float_read_write_type = boost::multiprecision::number<cpp_bin_float_read_write_backend_type, boost::multiprecision::et_off>;
auto rd_string(const char* pstr) -> bool;
constexpr auto rd_string(const char* pstr) -> bool;
constexpr auto add_unchecked(const cpp_double_fp_backend& v) -> void
{
@@ -1041,6 +1030,21 @@ class cpp_double_fp_backend
data = arithmetic::two_sum(data.first, v.data.first);
if (cpp_df_qf_detail::ccmath::isinf(data.first))
{
// Handle overflow.
const bool b_neg { (data.first < float_type { 0.0F }) };
*this = cpp_double_fp_backend::my_value_inf();
if (b_neg)
{
negate();
}
return;
}
data = arithmetic::two_hilo_sum(data.first, data.second + thi_tlo.first);
data = arithmetic::two_hilo_sum(data.first, thi_tlo.second + data.second);
@@ -1052,6 +1056,19 @@ class cpp_double_fp_backend
data = arithmetic::two_sum(data.first, v_first);
if (cpp_df_qf_detail::ccmath::isinf(data.first))
{
// Handle overflow.
*this = cpp_double_fp_backend::my_value_inf();
if (data.first)
{
negate();
}
return;
}
data = arithmetic::two_hilo_sum(data.first, data.second + thi);
data = arithmetic::two_hilo_sum(data.first, data.second);
@@ -1156,7 +1173,7 @@ class cpp_double_fp_backend
};
template <typename FloatingPointType>
auto cpp_double_fp_backend<FloatingPointType>::rd_string(const char* pstr) -> bool
constexpr auto cpp_double_fp_backend<FloatingPointType>::rd_string(const char* pstr) -> bool
{
cpp_bin_float_read_write_type f_bin { pstr };
@@ -2458,7 +2475,7 @@ constexpr auto eval_convert_to(OtherFloatingPointType* result, const cpp_double_
}
template <typename FloatingPointType>
auto hash_value(const cpp_double_fp_backend<FloatingPointType>& a) -> ::std::size_t
constexpr auto hash_value(const cpp_double_fp_backend<FloatingPointType>& a) -> ::std::size_t
{
return a.hash();
}
+23 -4
View File
@@ -499,8 +499,6 @@ namespace local
result_is_ok = (result_unf_is_ok && result_is_ok);
}
// TBD: See open issues for reminder to get this working in cpp_double_fp_backend.
BOOST_IF_CONSTEXPR(!::has_poor_exp_range_or_precision_support<float_type>::value)
{
using std::ldexp;
@@ -524,8 +522,6 @@ namespace local
result_is_ok = (result_ovf_is_ok && result_is_ok);
}
// TBD: See open issues for reminder to get this working in cpp_double_fp_backend.
BOOST_IF_CONSTEXPR(!::has_poor_exp_range_or_precision_support<float_type>::value)
{
using std::ldexp;
@@ -549,6 +545,29 @@ namespace local
result_is_ok = (result_ovf_is_ok && result_is_ok);
}
{
using std::ldexp;
float_type flt_near_lowest { -ldexp((std::numeric_limits<float_type>::max)(), -1) };
const float_type neg_flt_less_near_max { -ldexp((std::numeric_limits<float_type>::max)(), -4) };
unsigned index { };
while((index < max_index) && (!(boost::multiprecision::isinf)(flt_near_lowest)))
{
flt_near_lowest += (neg_flt_less_near_max * dis(gen));
++index;
}
const bool result_ovf_is_ok { ((index > 1U) && (index < max_index)) && signbit(flt_near_lowest) };
BOOST_TEST(result_ovf_is_ok);
result_is_ok = (result_ovf_is_ok && result_is_ok);
}
for(int n_loop = static_cast<int>(INT8_C(-16)); n_loop < static_cast<int>(INT8_C(-8)); ++n_loop)
{
using std::ldexp;