From c1f51b1ddc1d73c55fbb80d46df0a9a635b28059 Mon Sep 17 00:00:00 2001 From: ckormanyos Date: Sat, 2 May 2026 13:10:46 +0200 Subject: [PATCH 1/3] Potential proposal for 1384 --- include/boost/decimal/cmath.hpp | 1 + include/boost/decimal/detail/fwd_log.hpp | 39 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 include/boost/decimal/detail/fwd_log.hpp diff --git a/include/boost/decimal/cmath.hpp b/include/boost/decimal/cmath.hpp index 76e6fc110..8cbcfbdab 100644 --- a/include/boost/decimal/cmath.hpp +++ b/include/boost/decimal/cmath.hpp @@ -5,6 +5,7 @@ #ifndef BOOST_DECIMAL_CMATH_HPP #define BOOST_DECIMAL_CMATH_HPP +#include #include #include #include diff --git a/include/boost/decimal/detail/fwd_log.hpp b/include/boost/decimal/detail/fwd_log.hpp new file mode 100644 index 000000000..43e7628f7 --- /dev/null +++ b/include/boost/decimal/detail/fwd_log.hpp @@ -0,0 +1,39 @@ +// Copyright 2026 Christopher Kormanyos +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_DECIMAL_FWD_LOG_HPP +#define BOOST_DECIMAL_FWD_LOG_HPP + +#include + +namespace boost { +namespace decimal { + +// Forward declarationf of logarithmic functions. +// See also: https://github.com/boostorg/decimal/issues/1384 + +BOOST_DECIMAL_EXPORT template +constexpr auto ilogb(const T d) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); + +BOOST_DECIMAL_EXPORT template +constexpr auto log(const T x) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); + +BOOST_DECIMAL_EXPORT template +constexpr auto log1p(const T x) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); + +BOOST_DECIMAL_EXPORT template +constexpr auto log10(const T x) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); + +BOOST_DECIMAL_EXPORT template +constexpr auto log2(const T x) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); + +} // namespace decimal +} // namespace boost + +#endif // BOOST_DECIMAL_FWD_LOG_HPP From f994f3acc4747278853702640a7212b370f946f3 Mon Sep 17 00:00:00 2001 From: ckormanyos Date: Sat, 2 May 2026 20:02:36 +0200 Subject: [PATCH 2/3] More robust treatment and test of 1384 --- include/boost/decimal/detail/cmath/acosh.hpp | 6 +-- include/boost/decimal/detail/cmath/asinh.hpp | 6 +-- include/boost/decimal/detail/cmath/atanh.hpp | 4 +- .../decimal/detail/cmath/impl/ellint_impl.hpp | 2 +- include/boost/decimal/detail/cmath/lgamma.hpp | 8 ++-- include/boost/decimal/detail/cmath/log.hpp | 4 +- include/boost/decimal/detail/cmath/log10.hpp | 2 +- include/boost/decimal/detail/cmath/log1p.hpp | 2 +- include/boost/decimal/detail/cmath/log2.hpp | 2 +- include/boost/decimal/detail/cmath/pow.hpp | 2 +- .../decimal/detail/cmath/riemann_zeta.hpp | 2 +- include/boost/decimal/detail/cmath/tgamma.hpp | 2 +- test/Jamfile | 5 ++- test/github_issue_1384.cpp | 38 +++++++++++++++++++ 14 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 test/github_issue_1384.cpp diff --git a/include/boost/decimal/detail/cmath/acosh.hpp b/include/boost/decimal/detail/cmath/acosh.hpp index f1e514e86..6605a85eb 100644 --- a/include/boost/decimal/detail/cmath/acosh.hpp +++ b/include/boost/decimal/detail/cmath/acosh.hpp @@ -76,7 +76,7 @@ constexpr auto acosh_impl(const T x) noexcept { // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/06/01/06/01/0001/ // approximation by laurent series in 1/x at 0+ order from -1 to 0 - result = log(x) + numbers::ln2_v; + result = ::boost::decimal::log(x) + numbers::ln2_v; } else if (x < T { 15, -1 }) { @@ -85,12 +85,12 @@ constexpr auto acosh_impl(const T x) noexcept const auto two_y = y + y; - result = log1p(y + sqrt((y * y) + two_y)); + result = ::boost::decimal::log1p(y + sqrt((y * y) + two_y)); } else { // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/ - return(log(x + sqrt((x * x) - one))); + return(::boost::decimal::log(x + sqrt((x * x) - one))); } } else diff --git a/include/boost/decimal/detail/cmath/asinh.hpp b/include/boost/decimal/detail/cmath/asinh.hpp index 039c127dc..809e48480 100644 --- a/include/boost/decimal/detail/cmath/asinh.hpp +++ b/include/boost/decimal/detail/cmath/asinh.hpp @@ -52,17 +52,17 @@ constexpr auto asinh_impl(const T x) noexcept { // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/06/01/06/01/0001/ // approximation by laurent series in 1/x at 0+ order from -1 to 1 - result = numbers::ln2_v + log(x) + one / (T { 4, 0 } * xsq); + result = numbers::ln2_v + ::boost::decimal::log(x) + one / (T { 4, 0 } * xsq); } else if(x >= T { 5 , -1 }) { // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/02/ - result = log(x + sqrt(xsq + one)); + result = ::boost::decimal::log(x + sqrt(xsq + one)); } else if (x >= fourth_root_epsilon) { // As below, but rearranged to preserve digits: - result = log1p(x + (sqrt(one + xsq) - one)); + result = ::boost::decimal::log1p(x + (sqrt(one + xsq) - one)); } else { diff --git a/include/boost/decimal/detail/cmath/atanh.hpp b/include/boost/decimal/detail/cmath/atanh.hpp index 8f1fd13c8..b4758d7b0 100644 --- a/include/boost/decimal/detail/cmath/atanh.hpp +++ b/include/boost/decimal/detail/cmath/atanh.hpp @@ -62,11 +62,11 @@ constexpr auto atanh_impl(const T x) noexcept if(xx < half) { - result = (log1p(xx) - log1p(-xx)) / 2; + result = (::boost::decimal::log1p(xx) - ::boost::decimal::log1p(-xx)) / 2; } else { - result = (log((one + xx) / (one - xx)) / 2); + result = (::boost::decimal::log((one + xx) / (one - xx)) / 2); } } else diff --git a/include/boost/decimal/detail/cmath/impl/ellint_impl.hpp b/include/boost/decimal/detail/cmath/impl/ellint_impl.hpp index b86584311..7691be447 100644 --- a/include/boost/decimal/detail/cmath/impl/ellint_impl.hpp +++ b/include/boost/decimal/detail/cmath/impl/ellint_impl.hpp @@ -77,7 +77,7 @@ constexpr auto agm(T phi, const T sp { sin(phi) }; - Fpm = phi_is_pi_half ? std::numeric_limits::quiet_NaN() : log((one + sp) / (one - sp)) / 2; + Fpm = phi_is_pi_half ? std::numeric_limits::quiet_NaN() : ::boost::decimal::log((one + sp) / (one - sp)) / 2; if(has_e) { diff --git a/include/boost/decimal/detail/cmath/lgamma.hpp b/include/boost/decimal/detail/cmath/lgamma.hpp index 080b9972c..617d8efe5 100644 --- a/include/boost/decimal/detail/cmath/lgamma.hpp +++ b/include/boost/decimal/detail/cmath/lgamma.hpp @@ -81,7 +81,7 @@ constexpr auto lgamma_impl(const T x) noexcept const auto phase = sin(numbers::pi_v * za); - result = log(numbers::pi_v) - log(abs(phase)) - lgamma(za); + result = ::boost::decimal::log(numbers::pi_v) - ::boost::decimal::log(abs(phase)) - lgamma(za); } else { @@ -97,11 +97,11 @@ constexpr auto lgamma_impl(const T x) noexcept // Perform the Taylor series expansion. result = (x * fma(detail::lgamma_taylor_series_expansion(x), x, -numbers::egamma_v)) - - log(x); + - ::boost::decimal::log(x); } else if (x < T { asymp_cutoff }) { - result = log(tgamma(x)); + result = ::boost::decimal::log(tgamma(x)); } else { @@ -111,7 +111,7 @@ constexpr auto lgamma_impl(const T x) noexcept constexpr T half { 5, -1 }; - result = (((x - half) * (log(x)) - x)) + log(detail::tgamma_series_expansion_asymp(one / x)); + result = (((x - half) * (::boost::decimal::log(x)) - x)) + ::boost::decimal::log(detail::tgamma_series_expansion_asymp(one / x)); } } } diff --git a/include/boost/decimal/detail/cmath/log.hpp b/include/boost/decimal/detail/cmath/log.hpp index 6dea61f01..a8c34928b 100644 --- a/include/boost/decimal/detail/cmath/log.hpp +++ b/include/boost/decimal/detail/cmath/log.hpp @@ -53,11 +53,11 @@ constexpr auto log_impl(const T x) noexcept else if (x < one) { // Handle reflection. - result = -log(one / x); + result = -::boost::decimal::log(one / x); } else if(x > one) { - // Use the implementation of log10 in order to compute the natural + // Use the implementation of ::boost::decimal::log10 in order to compute the natural // logarithm. The base of the boost::decimal library is, in fact, // base-10. And so, somewhat uncommonly, the fastest and most accurate // logarithm in this system is log10 in base-10. diff --git a/include/boost/decimal/detail/cmath/log10.hpp b/include/boost/decimal/detail/cmath/log10.hpp index 49f3a95f4..468180173 100644 --- a/include/boost/decimal/detail/cmath/log10.hpp +++ b/include/boost/decimal/detail/cmath/log10.hpp @@ -79,7 +79,7 @@ constexpr auto log10_impl(const T x) noexcept if (x < one) { // Handle reflection. - result = -log10(one / x); + result = -::boost::decimal::log10(one / x); } else if(x > one) { diff --git a/include/boost/decimal/detail/cmath/log1p.hpp b/include/boost/decimal/detail/cmath/log1p.hpp index d23de14f1..f16884a35 100644 --- a/include/boost/decimal/detail/cmath/log1p.hpp +++ b/include/boost/decimal/detail/cmath/log1p.hpp @@ -61,7 +61,7 @@ constexpr auto log1p_impl(const T x) noexcept { if (x > T { 5, -1 }) { - result = log(x + one); + result = ::boost::decimal::log(x + one); } else { diff --git a/include/boost/decimal/detail/cmath/log2.hpp b/include/boost/decimal/detail/cmath/log2.hpp index c4ce12981..95fece461 100644 --- a/include/boost/decimal/detail/cmath/log2.hpp +++ b/include/boost/decimal/detail/cmath/log2.hpp @@ -27,7 +27,7 @@ template constexpr auto log2_impl(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - return log(x) / numbers::ln2_v; + return ::boost::decimal::log(x) / numbers::ln2_v; } } //namespace detail diff --git a/include/boost/decimal/detail/cmath/pow.hpp b/include/boost/decimal/detail/cmath/pow.hpp index 87a491837..27e6ff8ed 100644 --- a/include/boost/decimal/detail/cmath/pow.hpp +++ b/include/boost/decimal/detail/cmath/pow.hpp @@ -229,7 +229,7 @@ constexpr auto pow(const T x, const T a) noexcept #endif else { - const T a_log_x { a * log(x) }; + const T a_log_x { a * ::boost::decimal::log(x) }; result = exp(a_log_x); } diff --git a/include/boost/decimal/detail/cmath/riemann_zeta.hpp b/include/boost/decimal/detail/cmath/riemann_zeta.hpp index 583de318d..ba51f882f 100644 --- a/include/boost/decimal/detail/cmath/riemann_zeta.hpp +++ b/include/boost/decimal/detail/cmath/riemann_zeta.hpp @@ -110,7 +110,7 @@ constexpr auto riemann_zeta_impl(const T x) noexcept constexpr std::size_t n_primes = std::tuple_size::value; - const T lg10_max_prime { log10(detail::prime_table::primes[n_primes - 1U]) }; + const T lg10_max_prime { ::boost::decimal::log10(detail::prime_table::primes[n_primes - 1U]) }; if((x * lg10_max_prime) > std::numeric_limits::digits10) { diff --git a/include/boost/decimal/detail/cmath/tgamma.hpp b/include/boost/decimal/detail/cmath/tgamma.hpp index fe3222c5b..d521d2a35 100644 --- a/include/boost/decimal/detail/cmath/tgamma.hpp +++ b/include/boost/decimal/detail/cmath/tgamma.hpp @@ -115,7 +115,7 @@ constexpr auto tgamma_impl(const T x) noexcept { // Use large-argument asymptotic expansion. - const T prefix { exp(((x - T { 5, -1 }) * log(x)) - x) }; + const T prefix { exp(((x - T { 5, -1 }) * ::boost::decimal::log(x)) - x) }; result = prefix * detail::tgamma_series_expansion_asymp(one / x); } diff --git a/test/Jamfile b/test/Jamfile index 1699a65ff..9c1398515 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -1,6 +1,6 @@ # Copyright 2022 Peter Dimov -# 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 @@ -93,6 +93,7 @@ run github_issue_1319.cpp ; run github_issue_1329.cpp ; run github_issue_1361.cpp ; run github_issue_1378.cpp ; +run github_issue_1384.cpp ; run link_1.cpp link_2.cpp link_3.cpp ; run quick.cpp ; diff --git a/test/github_issue_1384.cpp b/test/github_issue_1384.cpp new file mode 100644 index 000000000..54aebc3d7 --- /dev/null +++ b/test/github_issue_1384.cpp @@ -0,0 +1,38 @@ + +#include + +// This simulates upstream inclusion of Boost.Log. At the time of +// hash commit e9951622837f63cf0020b22834ad96b01293fd07, this failed. + +// This odd-looking test in CI is intended to ensure that such failures +// no longer occur in the future and that the namespace resolution +// remains unequivocal. + +namespace boost { +namespace log { + +auto do_something() -> void +{ +} + +} // namespace log +} // namespace boost + +#include + +auto main() -> int; + +auto main() -> int +{ + using local_decimal_type = boost::decimal::decimal64_t; + + const local_decimal_type arg_dec { 1.23456 }; + + const local_decimal_type result1 { acosh(arg_dec) }; + const local_decimal_type result2 { lgamma(arg_dec) }; + + BOOST_TEST(result1 > local_decimal_type { 0.0 }); + BOOST_TEST(result2 < local_decimal_type { 0.0 }); + + return boost::report_errors(); +} From 405130ae52ccd02ba58d5d70b4e73c5ef7b22ae7 Mon Sep 17 00:00:00 2001 From: ckormanyos Date: Sun, 3 May 2026 08:34:16 +0200 Subject: [PATCH 3/3] Improve 1384 test case --- test/github_issue_1384.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/test/github_issue_1384.cpp b/test/github_issue_1384.cpp index 54aebc3d7..56377d2da 100644 --- a/test/github_issue_1384.cpp +++ b/test/github_issue_1384.cpp @@ -11,9 +11,13 @@ namespace boost { namespace log { -auto do_something() -> void -{ -} +auto do_something() -> void; + +// The presence of this namespace-local subroutine itself conflicted +// (at the time of the issue) with Boost.Log. So this behavior is +// simulated here. + +auto do_something() -> void { } // LCOV_EXCL_LINE } // namespace log } // namespace boost @@ -24,15 +28,24 @@ auto main() -> int; auto main() -> int { + boost::log::do_something(); // LCOV_EXCL_LINE + using local_decimal_type = boost::decimal::decimal64_t; - const local_decimal_type arg_dec { 1.23456 }; + const local_decimal_type arg_dec { 123456, -5 }; + // N[ArcCosh[123456/100000], 20] const local_decimal_type result1 { acosh(arg_dec) }; + + // N[Log[Gamma[123456/100000]], 20] const local_decimal_type result2 { lgamma(arg_dec) }; - BOOST_TEST(result1 > local_decimal_type { 0.0 }); - BOOST_TEST(result2 < local_decimal_type { 0.0 }); + // N[Zeta[123456/10000], 20] + const local_decimal_type result3 { riemann_zeta(arg_dec * local_decimal_type { 10.0 }) }; + + BOOST_TEST(result1 > local_decimal_type { 0.0 }); // 0.67219624862864254285 + BOOST_TEST(result2 < local_decimal_type { 0.0 }); // -0.094616414889227312801 + BOOST_TEST(result3 > local_decimal_type { 1.0 }); // 1.0001934607133929720 return boost::report_errors(); }