Avoid overflow of large numbers resulting from factorials, by using the logarithms as
intermediate results
\f
/* Statistical calculations. */
\f
/* Statistical calculations. */
-/* Returns the value of the gamma (factorial) function for an integer
+/* Returns the value of the logarithm of gamma (factorial) function for an integer
argument PT. */
static double
argument PT. */
static double
+log_gamma_int (double pt)
int i;
for (i = 2; i < pt; i++)
int i;
for (i = 2; i < pt; i++)
static inline double
Pr (int a, int b, int c, int d)
{
static inline double
Pr (int a, int b, int c, int d)
{
- return (gamma_int (a + b + 1.) / gamma_int (a + 1.)
- * gamma_int (c + d + 1.) / gamma_int (b + 1.)
- * gamma_int (a + c + 1.) / gamma_int (c + 1.)
- * gamma_int (b + d + 1.) / gamma_int (d + 1.)
- / gamma_int (a + b + c + d + 1.));
+ return exp (log_gamma_int (a + b + 1.) - log_gamma_int (a + 1.)
+ + log_gamma_int (c + d + 1.) - log_gamma_int (b + 1.)
+ + log_gamma_int (a + c + 1.) - log_gamma_int (c + 1.)
+ + log_gamma_int (b + d + 1.) - log_gamma_int (d + 1.)
+ - log_gamma_int (a + b + c + d + 1.));
}
/* Swap the contents of A and B. */
}
/* Swap the contents of A and B. */