in commons-numbers-combinatorics/src/main/java/org/apache/commons/numbers/combinatorics/BinomialCoefficientDouble.java [62:124]
public static double value(int n, int k) {
if (n <= LIMIT_N_LONG) {
// Delegate to the exact long result
return BinomialCoefficient.value(n, k);
}
final int m = BinomialCoefficient.checkBinomial(n, k);
if (m == 0) {
return 1;
}
if (m == 1) {
return n;
}
double result;
if (n <= MAX_FACTORIAL) {
// Small factorials are tabulated exactly
// n! / m! / (n-m)!
result = Factorial.uncheckedFactorial(n) /
Factorial.uncheckedFactorial(m) /
Factorial.uncheckedFactorial(n - m);
} else {
// Compute recursively using:
// (n choose m) = (n-1 choose m-1) * n / m
if (n <= SMALL_N || m <= SMALL_M) {
// No overflow possible
result = 1;
for (int i = 1; i <= m; i++) {
result *= n - m + i;
result /= i;
}
} else {
if (m > MAX_M) {
return Double.POSITIVE_INFINITY;
}
// Compute the initial part without overflow checks
result = 1;
for (int i = 1; i <= SMALL_M; i++) {
result *= n - m + i;
result /= i;
}
// Careful of overflow
for (int i = SMALL_M + 1; i <= m; i++) {
final double next = result * (n - m + i);
if (next > Double.MAX_VALUE) {
// Reverse order of terms
result /= i;
result *= n - m + i;
if (result > Double.MAX_VALUE) {
// Definite overflow
return Double.POSITIVE_INFINITY;
}
} else {
result = next / i;
}
}
}
}
return Math.floor(result + 0.5);
}