MCPcopy Create free account
hub / github.com/antlr/codebuff / binomial

Method binomial

output/java_guava/1.4.16/BigIntegerMath.java:426–462  ·  view source on GitHub ↗

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)

Source from the content-addressed store, hash-verified

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

Callers

nothing calls this directly

Calls 6

binomialMethod · 0.95
log2Method · 0.95
checkNonNegativeMethod · 0.45
checkArgumentMethod · 0.45
valueOfMethod · 0.45
divideMethod · 0.45

Tested by

no test coverage detected