boostorg / math

Boost.org math module
http://boost.org/libs/math
Boost Software License 1.0
313 stars 225 forks source link

Lost error handling in tgamma #1194

Closed jzmaddock closed 2 months ago

jzmaddock commented 2 months ago

The recent refactoring seems to have caused some error handling losses in tgamma, for example:

#include <boost/math/special_functions/gamma.hpp>

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());
   assert(errno == EDOM); // fails

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

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

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

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

   return 0;
}
mborland commented 2 months ago

I'll take a look. I'm pretty sure that the tgamma implementation function had a recursive case in it so it got separated into two functions.

Edit: https://github.com/boostorg/math/commit/18ef483309516837cfc382e39385445fc65cd379