public static double Function(double x)
{
double p, z;
double q = System.Math.Abs(x);
if (q > 33.0)
{
if (x < 0.0)
{
p = System.Math.Floor(q);
if (p == q)
throw new OverflowException();
z = q - p;
if (z > 0.5)
{
p += 1.0;
z = q - p;
}
z = q * System.Math.Sin(System.Math.PI * z);
if (z == 0.0)
throw new OverflowException();
z = System.Math.Abs(z);
z = System.Math.PI / (z * Stirling(q));
return -z;
}
else
{
return Stirling(x);
}
}
z = 1.0;
while (x >= 3.0)
{
x -= 1.0;
z *= x;
}
while (x < 0.0)
{
if (x == 0.0)
{
throw new ArithmeticException();
}
else if (x > -1.0E-9)
{
return (z / ((1.0 + 0.5772156649015329 * x) * x));
}
z /= x;
x += 1.0;
}
while (x < 2.0)
{
if (x == 0.0)
{
throw new ArithmeticException();
}
else if (x < 1.0E-9)
{
return (z / ((1.0 + 0.5772156649015329 * x) * x));
}
z /= x;
x += 1.0;
}
if ((x == 2.0) || (x == 3.0))
return z;
x -= 2.0;
p = Special.Polevl(x, gamma_P, 6);
q = Special.Polevl(x, gamma_Q, 7);
return z * p / q;
}