Returns n choose k, also known as the binomial coefficient of n and k, that is, n! / (k! (n - k)!). Warning: the result can take as much as O(k log n) space. @throws IllegalArgumentException if n < 0, k < 0, or k > n
(int n, int k)
| 424 | |
| 425 | |
| 426 | public static BigInteger binomial(int n, int k) { |
| 427 | checkNonNegative("n", n); |
| 428 | checkNonNegative("k", k); |
| 429 | checkArgument(k <= n, "k (%s) > n (%s)", k, n); |
| 430 | if (k > (n >> 1)) { |
| 431 | k = n - k; |
| 432 | } |
| 433 | if (k < LongMath.biggestBinomials.length && n <= LongMath.biggestBinomials[k]) { |
| 434 | return BigInteger.valueOf(LongMath.binomial(n, k)); |
| 435 | } |
| 436 | BigInteger accum = BigInteger.ONE; |
| 437 | long numeratorAccum = n; |
| 438 | long denominatorAccum = 1; |
| 439 | int bits = LongMath.log2(n, RoundingMode.CEILING); |
| 440 | int numeratorBits = bits; |
| 441 | for (int i = 1; i < k; i++) { |
| 442 | int p = n - i; |
| 443 | int q = i + 1; |
| 444 | |
| 445 | // log2(p) >= bits - 1, because p >= n/2 |
| 446 | if (numeratorBits + bits >= Long.SIZE - 1) { |
| 447 | // The numerator is as big as it can get without risking overflow. |
| 448 | // Multiply numeratorAccum / denominatorAccum into accum. |
| 449 | accum = |
| 450 | accum.multiply(BigInteger.valueOf(numeratorAccum)).divide(BigInteger.valueOf(denominatorAccum)); |
| 451 | numeratorAccum = p; |
| 452 | denominatorAccum = q; |
| 453 | numeratorBits = bits; |
| 454 | } else { |
| 455 | // We can definitely multiply into the long accumulators without overflowing them. |
| 456 | numeratorAccum *= p; |
| 457 | denominatorAccum *= q; |
| 458 | numeratorBits += bits; |
| 459 | } |
| 460 | } |
| 461 | return accum.multiply(BigInteger.valueOf(numeratorAccum)).divide(BigInteger.valueOf(denominatorAccum)); |
| 462 | } |
| 463 | |
| 464 | // Returns true if BigInteger.valueOf(x.longValue()).equals(x). |
| 465 |
nothing calls this directly
no test coverage detected