The easiest, but probably not the best in terms of accuracy and speed,
way would be to use logarithms.
Agreed, if n is reasonably large. I use the following code, which uses the
`double lgamma(double x)' which computes the logarithm of the gamma function.
I don't think it's standard C++, but there's probably a good chance you have
it, or something equivalent (on my linux system, the docs tell me it conforms
to C99, SVr4 and 4.3BSD).
inline double lfactorial(const unsigned n)
{
return lgamma(static_cast<double>(n+1));
}
inline double lbicof(const unsigned n, const unsigned k)
{
assert(k <= n);
return lfactorial(n)-lfactorial(k)-lfactorial(n-k);
}
inline double bicof(const unsigned n, const unsigned k)
{
return std::exp(lbicof(n,k));
}
inline double lbinom(const unsigned n, const unsigned k, const double p)
{
assert(p >= 0.0 && p <= 1.0);
return lbicof(n,k) + static_cast<double>(k)*std::log(p) + static_cast<double>(n-k)*std::log(1.0-p);
}
inline double binom(const unsigned n, const unsigned k, const double p)
{
return std::exp(lbinom(n,k,p));
}