public static double Stirling(double x)
{
double MAXSTIR = 143.01608;
double w = 1.0 / x;
double y = Math.Exp(x);
w = 1.0 + w * Special.Polevl(w, STIR, 4);
if (x > MAXSTIR)
{
double v = Math.Pow(x, 0.5 * x - 0.25);
if (Double.IsPositiveInfinity(v) && Double.IsPositiveInfinity(y))
{
// lim x -> inf { (x^(0.5*x - 0.25)) * (x^(0.5*x - 0.25) / exp(x)) }
y = Double.PositiveInfinity;
}
else
{
y = v * (v / y);
}
}
else
{
y = System.Math.Pow(x, x - 0.5) / y;
}
y = Constants.Sqrt2PI * y * w;
return y;
}