The following infinite serious require the calculation of factorial for non-integer, negative, real numbers:
(it is a way to calculate the circumference of an ellipse, a and b are the semi-major and semi minor axis and h is defined as:
h = (a-b)^2/(a+b)^2)
The factorial function can be extended to negative values via the Gamma function which is defined for all the real numbers that are not negative integers.
While coding the serious I tried boost::math::factorial and boost::math::tgamma which gives results only down to -1 (not included) -1.5 for example give an error.
#include <iostream>
#include <boost/math/special_functions/factorials.hpp>
int main()
{
double x;
double f;
double tg;
x = -0.5;
f = boost::math::factorial<double>(x);
tg = boost::math::tgamma<double>(x);
cout << "factorial of " << x << " = " << f << endl;
cout << "tgamma of " << x << " = " << tg << endl << endl;
x = -1.5;
f = boost::math::factorial<double>(x);
tg = boost::math::tgamma<double>(x);
cout << "factorial of " << x << " = " << f << endl;
cout << "tgamma of " << x << " = " << tg << endl << endl;
return 0;
}
the output:
factorial of -0.5 = 1
tgamma of -0.5 = -3.54491
terminate called after throwing an instance of 'boost::exception_detail::clone_implboost::exception_detail::error_info_injector<std::domain_error >' what(): Error in function boost::math::tgamma(long double): Evaluation of tgamma at a negative integer 0. Aborted (core dumped)
boost factorial:
boost factorial
boost tgamma:
boost tgamma
My questions:
- Is there an alternative to boost that can calculate the gamma function for its negative domain?
- I could not find in the boost documentation linked above mention of the implemented domain for factorials and tgamma functions. In fact I might simply be using them wrong. What is the way to ascertain what is indeed the domain/correct usage?
Thanks.
I understand what's going wrong. The
boost::math::factorial
function takes anunsigned
integer by definition:This means that if you call it with a double, it will get implicitly converted to unsigned. That's not what you want. Also,
factorial
ends up usingtgamma
internally, so you get this:Will end up doing this:
So it's attempting to give you
boost::math::factorial<long double> (i=4294967294)
Fix
Don't use
factorials
for other than non-negative integers.Live On Compiler Explorer
Prints:
It understandably overflows at
-2
, but that's correct.