Skip to content

Commit

Permalink
Merge pull request #1195 from boostorg/1194
Browse files Browse the repository at this point in the history
Fix removed tgamma error handling path
  • Loading branch information
mborland authored Sep 9, 2024
2 parents cb06899 + 9d13307 commit 84a7bdd
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 17 deletions.
39 changes: 22 additions & 17 deletions include/boost/math/special_functions/gamma.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,25 +197,30 @@ BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T gamma_imp(T z, const Policy& pol
{
BOOST_MATH_STD_USING

if(z <= -20)
{
constexpr auto function = "boost::math::tgamma<%1%>(%1%)";
T result = gamma_imp_final(T(-z), pol, l) * sinpx(z);
BOOST_MATH_INSTRUMENT_VARIABLE(result);
if((fabs(result) < 1) && (tools::max_value<T>() * fabs(result) < boost::math::constants::pi<T>()))
return -boost::math::sign(result) * policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
result = -boost::math::constants::pi<T>() / result;
if(result == 0)
return policies::raise_underflow_error<T>(function, "Result of tgamma is too small to represent.", pol);
if((boost::math::fpclassify)(result) == (int)BOOST_MATH_FP_SUBNORMAL)
return policies::raise_denorm_error<T>(function, "Result of tgamma is denormalized.", result, pol);
BOOST_MATH_INSTRUMENT_VARIABLE(result);
return result;
}
else
T result = 1;
constexpr auto function = "boost::math::tgamma<%1%>(%1%)";

if(z <= 0)
{
return gamma_imp_final(T(z), pol, l);
if(floor(z) == z)
return policies::raise_pole_error<T>(function, "Evaluation of tgamma at a negative integer %1%.", z, pol);
if(z <= -20)
{
result = gamma_imp_final(T(-z), pol, l) * sinpx(z);
BOOST_MATH_INSTRUMENT_VARIABLE(result);
if((fabs(result) < 1) && (tools::max_value<T>() * fabs(result) < boost::math::constants::pi<T>()))
return -boost::math::sign(result) * policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
result = -boost::math::constants::pi<T>() / result;
if(result == 0)
return policies::raise_underflow_error<T>(function, "Result of tgamma is too small to represent.", pol);
if((boost::math::fpclassify)(result) == BOOST_MATH_FP_SUBNORMAL)
return policies::raise_denorm_error<T>(function, "Result of tgamma is denormalized.", result, pol);
BOOST_MATH_INSTRUMENT_VARIABLE(result);
return result;
}
}

return gamma_imp_final(T(z), pol, l);
}

#ifdef BOOST_MATH_ENABLE_CUDA
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ test-suite special_fun :
[ run git_issue_1137.cpp ]
[ run git_issue_1139.cpp ]
[ run git_issue_1175.cpp ]
[ run git_issue_1194.cpp ]
[ run special_functions_test.cpp /boost/test//boost_unit_test_framework ]
[ run test_airy.cpp test_instances//test_instances pch_light /boost/test//boost_unit_test_framework ]
[ run test_bessel_j.cpp test_instances//test_instances pch_light /boost/test//boost_unit_test_framework ]
Expand Down
41 changes: 41 additions & 0 deletions test/git_issue_1194.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// (C) Copyright Matt Borland 2024.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include "math_unit_test.hpp"
#include <boost/math/special_functions/gamma.hpp>
#include <cerrno>

int main()
{
using c99_error_policy = ::boost::math::policies::policy<
::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>,
::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>,
::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>,
::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>,
::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error> >;

double val = -std::numeric_limits<double>::infinity();

val = boost::math::tgamma(val, c99_error_policy());
CHECK_EQUAL(errno, EDOM);

val = std::numeric_limits<double>::quiet_NaN();
val = boost::math::tgamma(val, c99_error_policy());
CHECK_EQUAL(errno, EDOM);

val = std::numeric_limits<double>::infinity();
val = boost::math::tgamma(val, c99_error_policy());
CHECK_EQUAL(errno, ERANGE);

val = 0;
val = boost::math::tgamma(val, c99_error_policy());
CHECK_EQUAL(errno, EDOM); // OK

val = -2;
val = boost::math::tgamma(val, c99_error_policy());
CHECK_EQUAL(errno, EDOM); // OK

return boost::math::test::report_errors();
}

0 comments on commit 84a7bdd

Please sign in to comment.