Returns n choose k, also known as the binomial coefficient of n and k, or Long#MAX_VALUE if the result does not fit in a long. @throws IllegalArgumentException if n < 0, k < 0, or k > n
(int n, int k)
| 877 | */ |
| 878 | |
| 879 | public static long binomial(int n, int k) { |
| 880 | checkNonNegative("n", n); |
| 881 | checkNonNegative("k", k); |
| 882 | checkArgument(k <= n, "k (%s) > n (%s)", k, n); |
| 883 | if (k > (n >> 1)) { |
| 884 | k = n - k; |
| 885 | } |
| 886 | switch (k) { |
| 887 | case 0: |
| 888 | return 1; |
| 889 | case 1: |
| 890 | return n; |
| 891 | default: |
| 892 | if (n < factorials.length) { |
| 893 | return factorials[n] / (factorials[k] * factorials[n - k]); |
| 894 | } else if (k >= biggestBinomials.length || n > biggestBinomials[k]) { |
| 895 | return Long.MAX_VALUE; |
| 896 | } |
| 897 | else if (k < biggestSimpleBinomials.length && n <= biggestSimpleBinomials[k]) { |
| 898 | // guaranteed not to overflow |
| 899 | long result = n--; |
| 900 | for (int i = 2; i <= k; n--, i++) { |
| 901 | result *= n; |
| 902 | result /= i; |
| 903 | } |
| 904 | return result; |
| 905 | } else { |
| 906 | int nBits = LongMath.log2(n, RoundingMode.CEILING); |
| 907 | long result = 1; |
| 908 | long numerator = n--; |
| 909 | long denominator = 1; |
| 910 | int numeratorBits = nBits; |
| 911 | // This is an upper bound on log2(numerator, ceiling). |
| 912 | |
| 913 | /* |
| 914 | * We want to do this in long math for speed, but want to avoid overflow. We adapt the |
| 915 | * technique previously used by BigIntegerMath: maintain separate numerator and |
| 916 | * denominator accumulators, multiplying the fraction into result when near overflow. |
| 917 | */ |
| 918 | for (int i = 2; i <= k; i++, n--) { |
| 919 | if (numeratorBits + nBits < Long.SIZE - 1) { |
| 920 | // It's definitely safe to multiply into numerator and denominator. |
| 921 | numerator *= n; |
| 922 | denominator *= i; |
| 923 | numeratorBits += nBits; |
| 924 | } else { |
| 925 | // It might not be safe to multiply into numerator and denominator, |
| 926 | // so multiply (numerator / denominator) into result. |
| 927 | result = multiplyFraction(result, numerator, denominator); |
| 928 | numerator = n; |
| 929 | denominator = i; |
| 930 | numeratorBits = nBits; |
| 931 | } |
| 932 | } |
| 933 | return multiplyFraction(result, numerator, denominator); |
| 934 | } |
| 935 | } |
| 936 | } |
no test coverage detected