// $Id: choose.c,v 1.3 2000/10/20 01:21:48 trow Exp $
#include "mconf.h"
double
factorial (int n)
{
static double lookup[24] = {
1.,
1.,
2.,
6.,
24.,
120.,
720.,
5040.,
40320.,
362880.,
3628800.,
39916800.,
479001600.,
6227020800.,
87178291200.,
1307674368000.,
20922789888000.,
355687428096000.,
6402373705728000.,
121645100408832000.,
2432902008176640000.,
51090942171709440000.,
1124000727777607680000.,
25852016738884976640000.
};
if (n < 0) {
return mtherr ("factorial", 1);
} else if (n < 24)
return lookup[n];
else
return floor (exp (log_factorial (n)) + 0.5);
}
double
log_factorial (int n)
{
if (n < 0) {
return mtherr ("log_factorial", 1);
}
return lgam (1.0 + n);
}
double
choose (int n, int k)
{
if (n < 1 || k < 0 || k > n)
return 0;
else if (k == 0 || k == n)
return 1;
else if (k == 1 || k == n - 1)
return n;
else if (n < 13)
return factorial (n) / (factorial (k) * factorial (n - k));
else
return floor (exp (log_choose (n, k)) + 0.5);
}
double
log_choose (int n, int k)
{
return log_factorial (n) - log_factorial (k) - log_factorial (n - k);
}
// $Id: choose.c,v 1.3 2000/10/20 01:21:48 trow Exp $
syntax highlighted by Code2HTML, v. 0.9.1