diff --git a/include/boost/decimal/detail/cmath/cosh.hpp b/include/boost/decimal/detail/cmath/cosh.hpp index a48e912b5..6e1e306b3 100644 --- a/include/boost/decimal/detail/cmath/cosh.hpp +++ b/include/boost/decimal/detail/cmath/cosh.hpp @@ -67,13 +67,17 @@ constexpr auto cosh_impl(const T x) noexcept result = fma(result, xsq, one); } - else + else if (x > one) { const auto exp_pos_val = exp(x); - constexpr T two { 2, 0 }; + result = (exp_pos_val + (one / exp_pos_val)) / 2; + } + else + { + constexpr T local_cosh_one { numbers::e_v }; - result = (exp_pos_val + (one / exp_pos_val)) / two; + result = (local_cosh_one + (one / local_cosh_one)) / 2; } } } diff --git a/include/boost/decimal/detail/cmath/exp.hpp b/include/boost/decimal/detail/cmath/exp.hpp index 34429ebe6..364957603 100644 --- a/include/boost/decimal/detail/cmath/exp.hpp +++ b/include/boost/decimal/detail/cmath/exp.hpp @@ -58,6 +58,10 @@ constexpr auto exp_impl(T x) noexcept { result = one / exp(-x); } + else if(x == one) + { + result = numbers::e_v; + } else { // Scale the argument to 0 < x < log(2). diff --git a/test/test_cosh.cpp b/test/test_cosh.cpp index 4cc0719da..fa40f46fd 100644 --- a/test/test_cosh.cpp +++ b/test/test_cosh.cpp @@ -1,5 +1,5 @@ // Copyright 2023 -2024 Matt Borland -// Copyright 2023 -2024 Christopher Kormanyos +// Copyright 2023 -2026 Christopher Kormanyos // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -217,6 +217,32 @@ namespace local result_is_ok = (result_val_zero_neg_is_ok && result_is_ok); } + for(auto i = static_cast(UINT8_C(0)); i < static_cast(UINT8_C(4)); ++i) + { + static_cast(i); + + const auto val_cosh_one = + cosh + ( + decimal_type + { + static_cast + ( + ::my_one() + static_cast(dist(gen) - 1.0F) + ) + } + ); + + // N[Cosh[1], 40] + constexpr decimal_type local_cosh_one { "1.543080634815243778477905620757061682602" }; + + const auto result_val_one_is_ok = local::is_close_fraction(val_cosh_one, local_cosh_one, std::numeric_limits::epsilon() * 4); + + BOOST_TEST(result_val_one_is_ok); + + result_is_ok = (result_val_one_is_ok && result_is_ok); + } + return result_is_ok; } @@ -351,9 +377,9 @@ auto main() -> int const auto result_edge_is_ok = local::test_cosh_edge(); - const auto result_pos64_is_ok = local::test_cosh_64(64); + const auto result_pos64_is_ok = local::test_cosh_64(32); - const auto result_pos128_is_ok = local::test_cosh_128(400000); + const auto result_pos128_is_ok = local::test_cosh_128(32); BOOST_TEST(result_pos_is_ok); BOOST_TEST(result_neg_is_ok); @@ -390,5 +416,5 @@ auto main() -> int return (result_is_ok ? 0 : -1); } -auto my_zero() -> boost::decimal::decimal32_t& { static boost::decimal::decimal32_t val_zero { 0, 0 }; return val_zero; } -auto my_one () -> boost::decimal::decimal32_t& { static boost::decimal::decimal32_t val_one { 1, 0 }; return val_one; } +auto my_zero() -> boost::decimal::decimal32_t& { static boost::decimal::decimal32_t val_instance { 0 }; return val_instance; } +auto my_one () -> boost::decimal::decimal32_t& { static boost::decimal::decimal32_t val_instance { 1 }; return val_instance; } diff --git a/test/test_exp.cpp b/test/test_exp.cpp index ecf164cf3..68d837fa5 100644 --- a/test/test_exp.cpp +++ b/test/test_exp.cpp @@ -1,5 +1,5 @@ // Copyright 2023 - 2024 Matt Borland -// Copyright 2023 - 2024 Christopher Kormanyos +// Copyright 2023 - 2026 Christopher Kormanyos // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -22,8 +22,8 @@ #include -template auto my_zero() -> DecimalType& { using decimal_type = DecimalType; static decimal_type val_zero { 0, 0 }; return val_zero; } -template auto my_one () -> DecimalType& { using decimal_type = DecimalType; static decimal_type val_one { 1, 0 }; return val_one; } +template auto my_zero() -> DecimalType; +template auto my_one () -> DecimalType; namespace local { @@ -381,7 +381,7 @@ auto main() -> int } { - const auto result_pos128_is_ok = local::test_exp_128(8192); + const auto result_pos128_is_ok = local::test_exp_128(256); BOOST_TEST(result_pos128_is_ok); @@ -392,3 +392,6 @@ auto main() -> int return (result_is_ok ? 0 : -1); } + +template auto my_zero() -> DecimalType { using decimal_type = DecimalType; return decimal_type { 0 }; } +template auto my_one () -> DecimalType { using decimal_type = DecimalType; return decimal_type { 1 }; }