in commons-numbers-gamma/src/main/java/org/apache/commons/numbers/gamma/BoostBeta.java [956:997]
private static double binomialCCdf(int n, int k, double x, double y) {
double result = Math.pow(x, n);
if (result > Double.MIN_NORMAL) {
double term = result;
for (int i = n - 1; i > k; --i) {
term *= ((i + 1) * y) / ((n - i) * x);
result += term;
}
} else {
// First term underflows so we need to start at the mode of the
// distribution and work outwards:
int start = (int) (n * x);
if (start <= k + 1) {
start = k + 2;
}
// Update:
// Carefully compute this term to guard against extreme parameterisation
result = binomialTerm(n, start, x, y);
if (result == 0) {
// OK, starting slightly above the mode didn't work,
// we'll have to sum the terms the old fashioned way:
for (int i = start - 1; i > k; --i) {
result += binomialTerm(n, i, x, y);
}
} else {
double term = result;
final double startTerm = result;
for (int i = start - 1; i > k; --i) {
term *= ((i + 1) * y) / ((n - i) * x);
result += term;
}
term = startTerm;
for (int i = start + 1; i <= n; ++i) {
term *= (n - i + 1) * x / (i * y);
result += term;
}
}
}
return result;
}