| Home | Libraries | People | FAQ | More

### 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

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:

`boost::math::double_factorial(2);`

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:

`boost::math::double_factorial<double>(2);`

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
The argument to `double_factorial` is type `unsigned` even though technically -1!! is defined.

##### Accuracy

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

##### Testing

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

##### Implementation

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!)

and

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