Add more tests and also get more TBDs

This commit is contained in:
ckormanyos
2025-07-21 20:42:31 +02:00
parent 76224e2466
commit ccb113d75c

View File

@@ -5,6 +5,10 @@
// Some parts of this test file have been taken from the Boost.Decimal project.
#define TEST_CPP_BIN_FLOAT
#define TEST_CPP_DEC_FLOAT
#define TEST_CPP_DOUBLE_FLOAT
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_double_fp.hpp>
@@ -30,6 +34,9 @@ template<typename FloatType> auto my_one () noexcept -> FloatType&;
template<typename FloatType> auto my_inf () noexcept -> FloatType&;
template<typename FloatType> auto my_nan () noexcept -> FloatType&;
template<typename FloatType> auto my_generator_overflow() noexcept -> FloatType;
template<typename FloatType> auto my_generator_underflow() noexcept -> FloatType;
namespace local
{
template<typename IntegralTimePointType,
@@ -216,6 +223,8 @@ namespace local
}
#ifdef BOOST_HAS_INT128
// TBD: Is this supposed to work for cpp_double_double?
BOOST_IF_CONSTEXPR(!::has_poor_exp_range_or_precision_support<float_type>::value)
{
for(auto index = static_cast<unsigned>(UINT8_C(0)); index < static_cast<unsigned>(UINT8_C(64)); ++index)
{
@@ -266,7 +275,7 @@ namespace local
(str_n128 == str_ctrl)
&& (
(!is_neg) ? (val_n128 >= static_cast<boost::int128_type>((std::numeric_limits<signed long long>::max)()))
: (val_n128 <= static_cast<boost::int128_type>((std::numeric_limits<signed long long>::max)()))
: (val_n128 <= static_cast<boost::int128_type>(std::numeric_limits<signed long long>::lowest()))
)
);
@@ -490,6 +499,8 @@ 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;
@@ -513,6 +524,8 @@ 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;
@@ -669,11 +682,52 @@ namespace local
return result_is_ok;
}
template<class FloatType>
bool test_edges_ovf_und()
{
using float_type = FloatType;
std::mt19937_64 gen { time_point<typename std::mt19937_64::result_type>() };
auto dis =
std::uniform_real_distribution<float>
{
static_cast<float>(1.01F),
static_cast<float>(1.04F)
};
bool result_is_ok { true };
{
for(auto index = static_cast<unsigned>(UINT8_C(0)); index < static_cast<unsigned>(UINT8_C(16)); ++index)
{
static_cast<void>(index);
const float_type flt_ovf = ::my_generator_overflow<float_type>() * dis(gen);
const float_type flt_und = ::my_generator_underflow<float_type>() * dis(gen);
const bool
result_ovf_und_is_ok
{
((boost::multiprecision::isinf)(flt_ovf) && ((boost::multiprecision::fpclassify)(flt_und) == FP_ZERO))
};
BOOST_TEST(result_ovf_und_is_ok);
result_is_ok = (result_ovf_und_is_ok && result_is_ok);
}
}
return result_is_ok;
}
template<class FloatType>
bool test_edges_trig()
{
using float_type = FloatType;
std::mt19937_64 gen { time_point<typename std::mt19937_64::result_type>() };
auto dis =
std::uniform_real_distribution<float>
{
@@ -689,8 +743,6 @@ namespace local
BOOST_IF_CONSTEXPR(std::numeric_limits<float_type>::has_quiet_NaN)
{
std::mt19937_64 gen { UINT64_C(0xF00DCAFEDEADBEEF) };
for(auto index = static_cast<unsigned>(UINT8_C(0)); index < static_cast<unsigned>(UINT8_C(8)); ++index)
{
static_cast<void>(index);
@@ -875,29 +927,42 @@ namespace local
auto main() -> int
{
using bin_float_backend_type = boost::multiprecision::cpp_bin_float<50>;
{
using dec_float_backend_type = boost::multiprecision::cpp_dec_float<50>;
using bin_float_type = boost::multiprecision::number<bin_float_backend_type, boost::multiprecision::et_off>;
using dec_float_type = boost::multiprecision::number<dec_float_backend_type, boost::multiprecision::et_off>;
{
std::cout << "Testing type: " << typeid(bin_float_type).name() << std::endl;
static_cast<void>(local::test_edges<bin_float_type>());
static_cast<void>(local::test_edges_trig<bin_float_type>());
}
{
std::cout << "Testing type: " << typeid(dec_float_type).name() << std::endl;
static_cast<void>(local::test_edges<dec_float_type>());
static_cast<void>(local::test_edges_ovf_und<dec_float_type>());
static_cast<void>(local::test_edges_trig<dec_float_type>());
local::test_cpp_dec_float_rd_ovf_unf<dec_float_type>();
local::test_convert_and_back<double, dec_float_type>(0.0F);
local::test_cpp_dec_float_frexp_edge<dec_float_type>();
}
{
using bin_float_backend_type = boost::multiprecision::cpp_bin_float<50>;
using bin_float_type = boost::multiprecision::number<bin_float_backend_type, boost::multiprecision::et_off>;
std::cout << "Testing type: " << typeid(bin_float_type).name() << std::endl;
static_cast<void>(local::test_edges<bin_float_type>());
// TBD: This seemingly trivial test fails for cpp_bin_float.
//static_cast<void>(local::test_edges_ovf_und<bin_float_type>());
static_cast<void>(local::test_edges_trig<bin_float_type>());
}
{
using double_float_type = boost::multiprecision::cpp_double_double;
std::cout << "Testing type: " << typeid(double_float_type).name() << std::endl;
static_cast<void>(local::test_edges<double_float_type>());
static_cast<void>(local::test_edges_ovf_und<double_float_type>());
static_cast<void>(local::test_edges_trig<double_float_type>());
}
{
using big_bin_float_backend_type = boost::multiprecision::cpp_bin_float<512>;
using big_dec_float_backend_type = boost::multiprecision::cpp_dec_float<512>;
@@ -917,6 +982,62 @@ template<typename FloatType> auto my_one () noexcept -> FloatType& { using float
template<typename FloatType> auto my_inf () noexcept -> FloatType& { using float_type = FloatType; static float_type val_inf { std::numeric_limits<float_type>::infinity() }; return val_inf; }
template<typename FloatType> auto my_nan () noexcept -> FloatType& { using float_type = FloatType; static float_type val_nan { std::numeric_limits<float_type>::quiet_NaN() }; return val_nan; }
template<class FloatType>
static auto
overflow_expval_maker
{
[]()
{
std::stringstream strm { };
using float_type = FloatType;
strm << std::numeric_limits<float_type>::max_exponent10 + 4;
return strm.str();
}
};
template<class FloatType>
static auto
underflow_expval_maker
{
[]()
{
std::stringstream strm { };
using float_type = FloatType;
strm << std::numeric_limits<float_type>::min_exponent10 - 4;
return strm.str();
}
};
template<typename FloatType>
auto my_generator_overflow() noexcept -> FloatType
{
using float_type = FloatType;
const float_type flt_ovf("1.23E" + overflow_expval_maker<float_type>());
const float_type result(flt_ovf);
return result;
}
template<typename FloatType>
auto my_generator_underflow() noexcept -> FloatType
{
using float_type = FloatType;
float_type flt_und("1.23E" + underflow_expval_maker<float_type>());
const float_type result(flt_und);
return result;
}
#if (defined(__clang__) || defined(__GNUC__))
# pragma GCC diagnostic pop
#endif