Boost C++ Libraries of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.

Double Factorial

#include <boost/math/special_functions/factorials.hpp>
namespace boost{ namespace math{

template <class T>
T double_factorial(unsigned i);

template <class T, class Policy>
T double_factorial(unsigned i, const Policy&);

}} // namespaces

Returns i!!.

The final Policy argument is optional and can be used to control the behaviour of the function: how it handles errors, what level of precision to use etc. Refer to the policy documentation for more details.

May return the result of overflow_error if the result is too large to represent in type T. The implementation is designed to be optimised for small i where table lookup of i! is possible.

[Important] Important

The functions described above are templates where the template argument T can not be deduced from the arguments passed to the function. Therefore if you write something like:


You will get a (possibly perplexing) compiler error, usually indicating that there is no such function to be found. Instead you need to specify the return type explicitly and write:


So that the return type is known. Further, the template argument must be a real-valued type such as float or double and not an integer type - that would overflow far too easily!

The source code static_assert and comment just after the will be:

static_assert(!std::is_integral<T>::value, "Type T must not be an integral type");
// factorial<unsigned int>(n) is not implemented
// because it would overflow integral type T for too small n
// to be useful. Use instead a floating-point type,
// and convert to an unsigned type if essential, for example:
// unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
// See factorial documentation for more detail.
[Note] Note

The argument to double_factorial is type unsigned even though technically -1!! is defined.


The implementation uses a trivial adaptation of the factorial function, so error rates should be no more than a couple of epsilon higher.


The spot tests for the double factorial use data generated by Wolfram Alpha.


The double factorial is implemented in terms of the factorial and gamma functions using the relations:

(2n)!! = 2n * n!

(2n+1)!! = (2n+1)! / (2n n!)


(2n-1)!! = Γ((2n+1)/2) * 2n / sqrt(pi)