// Copyright 2024 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #ifndef BOOST_DECIMAL_DETAIL_CMATH_BETA_HPP #define BOOST_DECIMAL_DETAIL_CMATH_BETA_HPP #include // NOLINT(llvm-include-order) #include #include #include #include #include namespace boost { namespace decimal { namespace detail { template constexpr auto beta_impl(const T x, const T y) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { #ifndef BOOST_DECIMAL_FAST_MATH if (isnan(x) || isnan(y)) { return std::numeric_limits::quiet_NaN(); } #endif // The beta function is defined as tgamma(x) * tgamma(y) / tgamma(x + y) // If we use lgamma instead and then take the exp at the end we avoid // the easy case of numerical overflow const auto temp {lgamma(x) + lgamma(y) - lgamma(x + y)}; return exp(temp); } } // namespace detail BOOST_DECIMAL_EXPORT template constexpr auto beta(const T y, const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { using evaluation_type = detail::evaluation_type_t; return static_cast(detail::beta_impl(static_cast(y), static_cast(x))); } } // namespace decimal } // namespace boost #endif //BOOST_DECIMAL_DETAIL_CMATH_BETA_HPP