diff --git a/include/boost/decimal/detail/cmath/pow.hpp b/include/boost/decimal/detail/cmath/pow.hpp index 0dc3f8f98..87a491837 100644 --- a/include/boost/decimal/detail/cmath/pow.hpp +++ b/include/boost/decimal/detail/cmath/pow.hpp @@ -1,5 +1,5 @@ -// Copyright 2023 Matt Borland -// Copyright 2023 Christopher Kormanyos +// Copyright 2023 - 2026 Matt Borland +// Copyright 2023 - 2026 Christopher Kormanyos // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -151,27 +151,32 @@ constexpr auto pow(const T x, const T a) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { constexpr T zero { 0, 0 }; + constexpr T one { 1, 0 }; auto result = zero; + const auto fpc_a = fpclassify(a); + const auto na = static_cast(a); - if ((na == a) || ((na == 0) && (na == abs(a)))) + if (fpc_a == FP_ZERO) + { + // pow(base, +/-0) returns 1 for any base, even when base is NaN. + + result = one; + } + else if (na == a) { result = pow(x, na); } else { - constexpr T one { 1, 0 }; - const auto fpc_x = fpclassify(x); - const auto fpc_a = fpclassify(a); - if (fpc_a == FP_ZERO) + if ((fpc_x == FP_NAN) || (fpc_a == FP_NAN)) { - // pow(base, +/-0) returns 1 for any base, even when base is NaN. - - result = one; + // This line is known to be covered by tests. + result = std::numeric_limits::quiet_NaN(); // LCOV_EXCL_LINE } else if (fpc_x == FP_ZERO) { @@ -186,10 +191,6 @@ constexpr auto pow(const T x, const T a) noexcept result = (signbit(a) ? std::numeric_limits::infinity() : zero); } - else if (fpc_a == FP_NAN) - { - result = std::numeric_limits::quiet_NaN(); - } #else if (fpc_a == FP_NORMAL) { @@ -207,14 +208,6 @@ constexpr auto pow(const T x, const T a) noexcept result = (signbit(a) ? zero : std::numeric_limits::infinity()); } - else if (fpc_a == FP_NAN) - { - result = std::numeric_limits::quiet_NaN(); - } - } - else if (fpc_x != FP_NORMAL) - { - result = x; } #endif else diff --git a/test/Jamfile b/test/Jamfile index 7a8d168fa..fc393124f 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -29,6 +29,7 @@ project : requirements #gcc:-Wduplicated-branches gcc:-Wfloat-equal gcc:-Wshadow + gcc:-Wno-psabi # https://github.com/boostorg/decimal/issues/1291 # GCC-7 does not support extra-semi, just pick one to try gcc-13:-Wextra-semi diff --git a/test/test_asin.cpp b/test/test_asin.cpp index 68e750eb9..04ae7fb81 100644 --- a/test/test_asin.cpp +++ b/test/test_asin.cpp @@ -1,5 +1,5 @@ -// Copyright 2024 - 2025 Matt Borland -// Copyright 2024 - 2025 Christopher Kormanyos +// Copyright 2024 - 2026 Matt Borland +// Copyright 2024 - 2026 Christopher Kormanyos // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -48,6 +49,28 @@ using namespace boost::decimal; template auto my_zero() -> T; template auto my_one () -> T; +namespace local +{ + template + auto time_point() noexcept -> IntegralTimePointType + { + using local_integral_time_point_type = IntegralTimePointType; + using local_clock_type = ClockType; + + const auto current_now = + static_cast + ( + std::chrono::duration_cast + ( + local_clock_type::now().time_since_epoch() + ).count() + ); + + return static_cast(current_now); + } +} // namespace local + template void test_asin() { @@ -178,8 +201,36 @@ auto test_asin_edge() -> void constexpr T half_pi { numbers::pi_v / 2 }; - BOOST_TEST_EQ(asin(my_zero() + my_one()), half_pi); - BOOST_TEST_EQ(asin(my_zero() - my_one()), -half_pi); + std::random_device rd; + std::mt19937_64 gen(rd()); + + gen.seed(local::time_point()); + + auto dis = + std::uniform_real_distribution + { + static_cast(1.01F), + static_cast(1.04F) + }; + + BOOST_TEST_EQ(asin((my_zero() * static_cast(dis(gen))) + my_one()), half_pi); + BOOST_TEST_EQ(asin((my_zero() * static_cast(dis(gen))) - my_one()), -half_pi); + + for(auto i = static_cast(UINT8_C(0)); i < static_cast(UINT8_C(4)); ++i) + { + static_cast(i); + + const T near_one { my_one() * static_cast(dis(gen)) }; + + const T arg_one { T { static_cast(near_one) } }; + + const auto val_one_pos = asin(+arg_one); + const auto val_one_neg = asin(-arg_one); + + BOOST_TEST_EQ(val_one_pos, +half_pi); + BOOST_TEST_EQ(val_one_neg, -half_pi); + } + } template diff --git a/test/test_asinh.cpp b/test/test_asinh.cpp index 17e58cadf..a3ea1d5a0 100644 --- a/test/test_asinh.cpp +++ b/test/test_asinh.cpp @@ -1,5 +1,5 @@ // Copyright 2023 Matt Borland -// Copyright 2023 Christopher Kormanyos +// Copyright 2023 - 2026 Christopher Kormanyos // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -236,7 +236,8 @@ auto main() -> int ); const auto result_tiny_is_ok = local::test_asinh(INT32_C(4096), false, 1.001, 1.1); - const auto result_small_is_ok = local::test_asinh(INT32_C(96), false, 0.1, 1.59); + const auto result_small_is_ok = local::test_asinh(INT32_C(384), false, 0.1, 1.59); + const auto result_small_neg_is_ok = local::test_asinh(INT32_C(384), true, 0.1, 1.59); const auto result_medium_is_ok = local::test_asinh(INT32_C(48), false, 1.59, 10.1); const auto result_medium_neg_is_ok = local::test_asinh(INT32_C(48), true, 1.59, 10.1); const auto result_large_is_ok = local::test_asinh(INT32_C(48), false, 1.0E+01, 1.0E+19); @@ -244,6 +245,7 @@ auto main() -> int BOOST_TEST(result_eps_is_ok); BOOST_TEST(result_tiny_is_ok); BOOST_TEST(result_small_is_ok); + BOOST_TEST(result_small_neg_is_ok); BOOST_TEST(result_medium_is_ok); BOOST_TEST(result_medium_neg_is_ok); BOOST_TEST(result_large_is_ok); diff --git a/test/test_assoc_legendre.cpp b/test/test_assoc_legendre.cpp index 8ea3a82ba..bef7b45c0 100644 --- a/test/test_assoc_legendre.cpp +++ b/test/test_assoc_legendre.cpp @@ -5,6 +5,11 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4714) // Marked as forceinline but not inlined +#endif + #include "testing_config.hpp" #include @@ -28,22 +33,13 @@ # pragma GCC diagnostic ignored "-Wuseless-cast" #endif -// Windows in Github actions has a broken chrono header -#if defined(_WIN32) - -int main() -{ - return 0; -} - -#else - #include #include #include + +#include #include #include -#include static constexpr std::size_t N {10}; @@ -245,4 +241,6 @@ int main() return boost::report_errors(); } +#ifdef _MSC_VER +# pragma warning(pop) #endif diff --git a/test/test_frexp_ldexp.cpp b/test/test_frexp_ldexp.cpp index 5e3fa9615..bb0cf59b3 100644 --- a/test/test_frexp_ldexp.cpp +++ b/test/test_frexp_ldexp.cpp @@ -25,6 +25,7 @@ template auto my_zero() -> DecimalType&; template auto my_one () -> DecimalType&; template auto my_inf () -> DecimalType&; +template auto my_nan () -> DecimalType&; namespace local { @@ -244,27 +245,46 @@ namespace local auto result_is_ok = true; + for(auto index = static_cast(UINT8_C(0)); index < static_cast(UINT8_C(4)); ++index) { - frexp_dec = frexp(zero, &n_dec); + static_cast(index); + + const decimal_type arg_zero { ::my_zero() * static_cast(dist(gen)) }; + + frexp_dec = frexp(arg_zero, &n_dec); const auto result_zero_is_ok = ((frexp_dec == 0) && (n_dec == 0)); + result_is_ok = (result_zero_is_ok && result_is_ok); + BOOST_TEST(result_is_ok); } + for(auto index = static_cast(UINT8_C(0)); index < static_cast(UINT8_C(4)); ++index) { - frexp_dec = frexp(std::numeric_limits::infinity(), &n_dec); + static_cast(index); + + const decimal_type arg_inf { ::my_inf() * static_cast(dist(gen)) }; + + frexp_dec = frexp(arg_inf, &n_dec); const auto result_inf_is_ok = (isinf(frexp_dec) && (n_dec == 0)); result_is_ok = (result_inf_is_ok && result_is_ok); BOOST_TEST(result_is_ok); } + for(auto index = static_cast(UINT8_C(0)); index < static_cast(UINT8_C(4)); ++index) { - frexp_dec = frexp(std::numeric_limits::quiet_NaN(), &n_dec); + static_cast(index); + + const decimal_type arg_nan { ::my_nan() * static_cast(dist(gen)) }; + + frexp_dec = frexp(arg_nan, &n_dec); const auto result_nan_is_ok = (isnan(frexp_dec) && (n_dec == 0)); + result_is_ok = (result_nan_is_ok && result_is_ok); + BOOST_TEST(result_is_ok); } @@ -272,8 +292,7 @@ namespace local { static_cast(index); - decimal_type arg_inf { ::my_inf() }; - arg_inf *= static_cast(dist(gen)); + const decimal_type arg_inf { ::my_inf() * static_cast(dist(gen)) }; int n_dummy { }; const auto frexp_inf = frexp(arg_inf, &n_dummy); @@ -306,23 +325,6 @@ namespace local result_is_ok = (result_frexp_inf_is_ok && result_is_ok); } - for(auto index = static_cast(UINT8_C(0)); index < static_cast(UINT8_C(4)); ++index) - { - static_cast(index); - - decimal_type arg_nan { sqrt(-::my_one()) }; - arg_nan *= static_cast(dist(gen)); - - int n_dummy { }; - const auto frexp_nan = frexp(arg_nan, &n_dummy); - - const volatile auto result_frexp_nan_is_ok = isnan(frexp_nan); - - BOOST_TEST(result_frexp_nan_is_ok); - - result_is_ok = (result_frexp_nan_is_ok && result_is_ok); - } - return result_is_ok; } @@ -343,60 +345,59 @@ namespace local auto result_is_ok = true; + for(auto index = static_cast(UINT8_C(0)); index < static_cast(UINT8_C(4)); ++index) { - auto ldexp_dec = ldexp(static_cast(0.0), 0); + static_cast(index); + + const auto arg_zero { ::my_zero() * static_cast(dist(gen)) }; + + auto ldexp_dec = ldexp(arg_zero, 0); auto result_zero_is_ok = (ldexp_dec == 0); - ldexp_dec = ldexp(static_cast(0.0), 3); + ldexp_dec = ldexp(arg_zero, 3); result_zero_is_ok = ((ldexp_dec == 0) && result_zero_is_ok); result_is_ok = (result_zero_is_ok && result_is_ok); BOOST_TEST(result_is_ok); } + for(auto index = static_cast(UINT8_C(0)); index < static_cast(UINT8_C(4)); ++index) { - auto ldexp_dec = ldexp(std::numeric_limits::infinity(), 0); + static_cast(index); + + const auto arg_inf { ::my_inf() * static_cast(dist(gen)) }; + + auto ldexp_dec = ldexp(arg_inf, 0); auto result_inf_is_ok = isinf(ldexp_dec); - ldexp_dec = ldexp(std::numeric_limits::infinity(), 3); + ldexp_dec = ldexp(arg_inf, 3); result_inf_is_ok = (isinf(ldexp_dec) && result_inf_is_ok); result_is_ok = (result_inf_is_ok && result_is_ok); BOOST_TEST(result_is_ok); } - { - auto ldexp_dec = ldexp(std::numeric_limits::quiet_NaN(), 0); - auto result_nan_is_ok = isnan(ldexp_dec); - - ldexp_dec = ldexp(std::numeric_limits::quiet_NaN(), 3); - result_nan_is_ok = (isnan(ldexp_dec) && result_nan_is_ok); - - result_is_ok = (result_nan_is_ok && result_is_ok); - BOOST_TEST(result_is_ok); - } - for(auto index = static_cast(UINT8_C(0)); index < static_cast(UINT8_C(4)); ++index) { static_cast(index); - decimal_type arg_inf { ::my_inf() }; - arg_inf *= static_cast(dist(gen)); + const auto arg_nan { ::my_nan() * static_cast(dist(gen)) }; - const auto ldexp_inf = ldexp(arg_inf, 3); - - const volatile auto result_ldexp_inf_is_ok = isinf(ldexp_inf); + auto ldexp_dec = ldexp(arg_nan, 0); + auto result_nan_is_ok = isnan(ldexp_dec); - BOOST_TEST(result_ldexp_inf_is_ok); + ldexp_dec = ldexp(arg_nan, 3); + result_nan_is_ok = (isnan(ldexp_dec) && result_nan_is_ok); - result_is_ok = (result_ldexp_inf_is_ok && result_is_ok); + result_is_ok = (result_nan_is_ok && result_is_ok); + BOOST_TEST(result_is_ok); } for(auto index = static_cast(UINT8_C(0)); index < static_cast(UINT8_C(4)); ++index) { static_cast(index); - decimal_type + const decimal_type arg_inf { (::my_one() * static_cast(dist(gen))) @@ -416,8 +417,7 @@ namespace local { static_cast(index); - decimal_type arg_nan { sqrt(-::my_one()) }; - arg_nan *= static_cast(dist(gen)); + const decimal_type arg_nan { sqrt(-::my_one()) * static_cast(dist(gen)) }; const auto ldexp_nan = ldexp(arg_nan, 3); @@ -450,3 +450,4 @@ auto main() -> int template auto my_zero() -> DecimalType& { using decimal_type = DecimalType; static decimal_type val_zero { 0 }; return val_zero; } template auto my_one () -> DecimalType& { using decimal_type = DecimalType; static decimal_type val_one { 1 }; return val_one; } template auto my_inf () -> DecimalType& { using decimal_type = DecimalType; static decimal_type val_inf { std::numeric_limits::infinity() }; return val_inf; } +template auto my_nan () -> DecimalType& { using decimal_type = DecimalType; static decimal_type val_nan { std::numeric_limits::quiet_NaN() }; return val_nan; } diff --git a/test/test_lgamma.cpp b/test/test_lgamma.cpp index a00da2e3b..64a52cfa6 100644 --- a/test/test_lgamma.cpp +++ b/test/test_lgamma.cpp @@ -1,5 +1,5 @@ -// Copyright 2023 - 2024 Matt Borland -// Copyright 2023 - 2024 Christopher Kormanyos +// Copyright 2023 - 2026 Matt Borland +// Copyright 2023 - 2026 Christopher Kormanyos // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -139,9 +139,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x200) : UINT32_C(0x20); + constexpr std::uint32_t count { ((std::numeric_limits::digits10 < 10) ? UINT16_C(800) : UINT16_C(200)) }; #else - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x20) : UINT32_C(0x4); + constexpr std::uint32_t count { ((std::numeric_limits::digits10 < 10) ? UINT16_C(80) : UINT16_C(20)) }; #endif for( ; trials < count; ++trials) @@ -442,7 +442,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_special_issue385_is_ok = local::test_special_issue385(4096); + const auto result_special_issue385_is_ok = local::test_special_issue385(512); BOOST_TEST(result_special_issue385_is_ok); @@ -453,7 +453,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_lgamma_is_ok = local::test_lgamma(512, 0.01, 0.9); + const auto result_lgamma_is_ok = local::test_lgamma(128, 0.01, 0.9); BOOST_TEST(result_lgamma_is_ok); @@ -464,7 +464,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_lgamma_is_ok = local::test_lgamma(512, 1.1, 1.9); + const auto result_lgamma_is_ok = local::test_lgamma(128, 1.1, 1.9); BOOST_TEST(result_lgamma_is_ok); @@ -475,7 +475,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_lgamma_is_ok = local::test_lgamma(512, 2.1, 123.4); + const auto result_lgamma_is_ok = local::test_lgamma(128, 2.1, 123.4); BOOST_TEST(result_lgamma_is_ok); @@ -486,7 +486,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_lgamma_is_ok = local::test_lgamma(4096, 0.01, 0.9); + const auto result_lgamma_is_ok = local::test_lgamma(512, 0.01, 0.9); BOOST_TEST(result_lgamma_is_ok); @@ -497,7 +497,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_lgamma_is_ok = local::test_lgamma(4096, 1.1, 1.9); + const auto result_lgamma_is_ok = local::test_lgamma(512, 1.1, 1.9); BOOST_TEST(result_lgamma_is_ok); @@ -508,7 +508,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_lgamma_is_ok = local::test_lgamma(4096, 2.1, 123.4); + const auto result_lgamma_is_ok = local::test_lgamma(512, 2.1, 123.4); BOOST_TEST(result_lgamma_is_ok); @@ -517,7 +517,7 @@ auto main() -> int #if !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) { - const auto result_neg32_is_ok = local::test_lgamma_neg32(2048); + const auto result_neg32_is_ok = local::test_lgamma_neg32(512); BOOST_TEST(result_neg32_is_ok); @@ -538,7 +538,7 @@ auto main() -> int { #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE - const auto result_lgamma128_is_ok = local::test_lgamma_128(4096); + const auto result_lgamma128_is_ok = local::test_lgamma_128(2048); BOOST_TEST(result_lgamma128_is_ok); diff --git a/test/test_pow.cpp b/test/test_pow.cpp index f5d129f5e..7ff2f5724 100644 --- a/test/test_pow.cpp +++ b/test/test_pow.cpp @@ -1,5 +1,5 @@ -// Copyright 2023 - 2024 Matt Borland -// Copyright 2023 - 2024 Christopher Kormanyos +// Copyright 2023 - 2026 Matt Borland +// Copyright 2023 - 2026 Christopher Kormanyos // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -410,12 +410,12 @@ namespace local { static_cast(index); - const auto flt_near_one = dist(gen); + const auto flt_near_one = dist(gen); - const auto dec_pos_pos = pow( std::numeric_limits::quiet_NaN() * static_cast(flt_near_one), ::my_zero() * static_cast(dist(gen))); - const auto dec_pos_neg = pow( std::numeric_limits::quiet_NaN() * static_cast(flt_near_one), -::my_zero() * static_cast(dist(gen))); - const auto dec_neg_pos = pow(-std::numeric_limits::quiet_NaN() * static_cast(flt_near_one), ::my_zero() * static_cast(dist(gen))); - const auto dec_neg_neg = pow(-std::numeric_limits::quiet_NaN() * static_cast(flt_near_one), -::my_zero() * static_cast(dist(gen))); + const auto dec_pos_pos = pow( ::my_nan() * static_cast(flt_near_one), ::my_zero() * static_cast(dist(gen))); + const auto dec_pos_neg = pow( ::my_nan() * static_cast(flt_near_one), -::my_zero() * static_cast(dist(gen))); + const auto dec_neg_pos = pow(-::my_nan() * static_cast(flt_near_one), ::my_zero() * static_cast(dist(gen))); + const auto dec_neg_neg = pow(-::my_nan() * static_cast(flt_near_one), -::my_zero() * static_cast(dist(gen))); const auto flt_pos_pos = pow( std::numeric_limits::quiet_NaN() * flt_near_one, static_cast(0.0L)); const auto flt_pos_neg = pow( std::numeric_limits::quiet_NaN() * flt_near_one, -static_cast(0.0L)); @@ -532,8 +532,8 @@ namespace local const auto flt_a = dist_a(gen); - const auto dec_pos_pos = pow( ::my_zero(), std::numeric_limits::quiet_NaN() * static_cast(flt_a)); - const auto dec_neg_pos = pow(-::my_zero(), std::numeric_limits::quiet_NaN() * static_cast(flt_a)); + const auto dec_pos_pos = pow( ::my_zero(), ::my_nan() * static_cast(flt_a)); + const auto dec_neg_pos = pow(-::my_zero(), ::my_nan() * static_cast(flt_a)); const auto flt_pos_pos = pow( static_cast(0.0L), std::numeric_limits::quiet_NaN() * flt_a); const auto flt_neg_pos = pow(-static_cast(0.0L), std::numeric_limits::quiet_NaN() * flt_a); @@ -616,10 +616,10 @@ namespace local const auto flt_a = dist_a(gen); - const auto dec_neg_neg = pow(-std::numeric_limits::infinity(), -static_cast(flt_a)); - const auto dec_neg_pos = pow(-std::numeric_limits::infinity(), static_cast(flt_a)); - const auto dec_pos_neg = pow( std::numeric_limits::infinity(), -static_cast(flt_a)); - const auto dec_pos_pos = pow( std::numeric_limits::infinity(), static_cast(flt_a)); + const auto dec_neg_neg = pow(-std::numeric_limits::infinity() * static_cast(dist(gen)), -static_cast(flt_a)); + const auto dec_neg_pos = pow(-std::numeric_limits::infinity() * static_cast(dist(gen)), static_cast(flt_a)); + const auto dec_pos_neg = pow( std::numeric_limits::infinity() * static_cast(dist(gen)), -static_cast(flt_a)); + const auto dec_pos_pos = pow( std::numeric_limits::infinity() * static_cast(dist(gen)), static_cast(flt_a)); const auto flt_neg_neg = pow(-std::numeric_limits::infinity(), -flt_a); const auto flt_neg_pos = pow(-std::numeric_limits::infinity(), flt_a); @@ -672,10 +672,10 @@ namespace local const auto flt_a = dist_a(gen); - const auto dec_neg_nan = pow(-std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN()); - const auto dec_pos_nan = pow( std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN()); - const auto dec_nan_neg = pow( std::numeric_limits::quiet_NaN(), -static_cast(flt_a)); - const auto dec_nan_pos = pow( std::numeric_limits::quiet_NaN(), static_cast(flt_a)); + const auto dec_neg_nan = pow(-std::numeric_limits::infinity(), ::my_nan() * static_cast(dist(gen))); + const auto dec_pos_nan = pow( std::numeric_limits::infinity(), ::my_nan() * static_cast(dist(gen))); + const auto dec_nan_neg = pow( ::my_nan() * static_cast(dist(gen)), -static_cast(flt_a)); + const auto dec_nan_pos = pow( ::my_nan() * static_cast(dist(gen)), static_cast(flt_a)); const auto flt_neg_nan = pow(-std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN()); const auto flt_pos_nan = pow( std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN()); diff --git a/test/test_tgamma.cpp b/test/test_tgamma.cpp index 04dad2006..7682f3e21 100644 --- a/test/test_tgamma.cpp +++ b/test/test_tgamma.cpp @@ -1,5 +1,5 @@ -// Copyright 2023 - 2024 Matt Borland -// Copyright 2023 - 2024 Christopher Kormanyos +// Copyright 2023 - 2026 Matt Borland +// Copyright 2023 - 2026 Christopher Kormanyos // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -107,9 +107,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x400) : UINT32_C(0x40); + constexpr std::uint32_t count { ((std::numeric_limits::digits10 < 10) ? UINT16_C(800) : UINT16_C(200)) }; #else - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x40) : UINT32_C(0x4); + constexpr std::uint32_t count { ((std::numeric_limits::digits10 < 10) ? UINT16_C(80) : UINT16_C(20)) }; #endif for( ; trials < count; ++trials) @@ -574,7 +574,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_tgamma_is_ok = local::test_tgamma(768, 0.01, 0.9); + const auto result_tgamma_is_ok = local::test_tgamma(128, 0.01, 0.9); BOOST_TEST(result_tgamma_is_ok); @@ -585,7 +585,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_tgamma_is_ok = local::test_tgamma(768, 2.1, 23.4); + const auto result_tgamma_is_ok = local::test_tgamma(128, 2.1, 23.4); BOOST_TEST(result_tgamma_is_ok); @@ -596,7 +596,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal_fast32_t; using float_type = float; - const auto result_tgamma_is_ok = local::test_tgamma(768, 2.1, 23.4); + const auto result_tgamma_is_ok = local::test_tgamma(128, 2.1, 23.4); BOOST_TEST(result_tgamma_is_ok); @@ -607,7 +607,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_tgamma_is_ok = local::test_tgamma(4096, 0.001, 0.9); + const auto result_tgamma_is_ok = local::test_tgamma(512, 0.001, 0.9); BOOST_TEST(result_tgamma_is_ok); @@ -618,7 +618,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_tgamma_is_ok = local::test_tgamma(4096, 2.1, 78.9); + const auto result_tgamma_is_ok = local::test_tgamma(512, 2.1, 78.9); BOOST_TEST(result_tgamma_is_ok); @@ -655,7 +655,7 @@ auto main() -> int } { - const auto result_tgamma64_is_ok = local::test_tgamma_64(4096); + const auto result_tgamma64_is_ok = local::test_tgamma_64(512); BOOST_TEST(result_tgamma64_is_ok); @@ -663,7 +663,7 @@ auto main() -> int } { - const auto result_tgamma64_is_ok = local::test_tgamma_64(4096); + const auto result_tgamma64_is_ok = local::test_tgamma_64(512); BOOST_TEST(result_tgamma64_is_ok); @@ -672,18 +672,18 @@ auto main() -> int #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE { - const auto result_tgamma128_lo_is_ok = local::test_tgamma_128_lo(4096); - const auto result_tgamma128_hi_is_ok = local::test_tgamma_128_hi(0x30'000); + const auto result_tgamma128_lo_is_ok = local::test_tgamma_128_lo(2048); + const auto result_tgamma128_hi_is_ok = local::test_tgamma_128_hi(2048); BOOST_TEST(result_tgamma128_lo_is_ok); BOOST_TEST(result_tgamma128_hi_is_ok); result_is_ok = (result_tgamma128_lo_is_ok && result_tgamma128_hi_is_ok && result_is_ok); } - + { - const auto result_tgamma128_lo_is_ok = local::test_tgamma_128_lo(4096); - const auto result_tgamma128_hi_is_ok = local::test_tgamma_128_hi(0x30'000); + const auto result_tgamma128_lo_is_ok = local::test_tgamma_128_lo(2048); + const auto result_tgamma128_hi_is_ok = local::test_tgamma_128_hi(2048); BOOST_TEST(result_tgamma128_lo_is_ok); BOOST_TEST(result_tgamma128_hi_is_ok); @@ -692,9 +692,9 @@ auto main() -> int } #endif - result_is_ok = ((boost::report_errors() == 0) && result_is_ok); + BOOST_TEST(result_is_ok); - return (result_is_ok ? 0 : -1); + return boost::report_errors(); } template auto my_zero() -> DecimalType& { using decimal_type = DecimalType; static decimal_type val_zero { 0 }; return val_zero; } diff --git a/test/test_zeta.cpp b/test/test_zeta.cpp index 9a9c4543a..2bcb8779c 100644 --- a/test/test_zeta.cpp +++ b/test/test_zeta.cpp @@ -1,11 +1,16 @@ -// Copyright 2024 Matt Borland -// Copyright 2024 Christoper Kormanyos +// Copyright 2024 - 2026 Matt Borland +// Copyright 2024 - 2026 Christoper Kormanyos // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4714) // Marked as forceinline but not inlined +#endif + #include "testing_config.hpp" #include @@ -29,24 +34,16 @@ # pragma GCC diagnostic ignored "-Wuseless-cast" #endif -// Windows in Github actions has a broken chrono header -#if defined(_WIN32) - -int main() -{ - return 0; -} - -#else - #include #include +#include #include #include #include template auto my_zero() -> DecimalType&; +template auto my_one () -> DecimalType&; template auto my_nan () -> DecimalType&; template auto my_inf () -> DecimalType&; @@ -210,13 +207,27 @@ auto test_riemann_zeta_edge() -> bool result_nan_is_ok = (isnan(riemann_zeta(decimal_type { 1 }))); result_is_ok = (result_nan_is_ok && result_is_ok); BOOST_TEST(result_is_ok); } + for(auto index = 0U; index < 8U; ++index) { + static_cast(index); + const decimal_type zero { ::my_zero() * decimal_type(dist(gen)) }; const decimal_type minus_half { -5, -1 }; const bool result_zero_is_ok = (riemann_zeta(zero) == minus_half); result_is_ok = (result_zero_is_ok && result_is_ok); BOOST_TEST(result_is_ok); } + + for(auto index = 0U; index < 8U; ++index) + { + static_cast(index); + + const int n_one { static_cast(::my_one() + decimal_type(dist(gen) / 150.0F)) }; + + const decimal_type one { n_one }; + + const bool result_one_is_ok = isnan(riemann_zeta(one)); result_is_ok = (result_one_is_ok && result_is_ok); BOOST_TEST(result_is_ok); + } } for(auto n = static_cast(UINT8_C(2)); n < static_cast(UINT8_C(6)); ++n) @@ -452,7 +463,10 @@ int main() } template auto my_zero() -> DecimalType& { using decimal_type = DecimalType; static decimal_type val_zero { 0 }; return val_zero; } +template auto my_one () -> DecimalType& { using decimal_type = DecimalType; static decimal_type val_one { 1 }; return val_one; } template auto my_nan () -> DecimalType& { using decimal_type = DecimalType; static decimal_type val_nan { std::numeric_limits::quiet_NaN() }; return val_nan; } template auto my_inf () -> DecimalType& { using decimal_type = DecimalType; static decimal_type val_inf { std::numeric_limits::infinity() }; return val_inf; } +#ifdef _MSC_VER +# pragma warning(pop) #endif