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)
| 894 | */ |
| 895 | |
| 896 | public static long binomial(int n, int k) { |
| 897 | checkNonNegative("n", n); |
| 898 | checkNonNegative("k", k); |
| 899 | checkArgument(k <= n, "k (%s) > n (%s)", k, n); |
| 900 | if (k > (n >> 1)) { |
| 901 | k = n - k; |
| 902 | } |
| 903 | switch (k) { |
| 904 | case 0: |
| 905 | return 1; |
| 906 | case 1: |
| 907 | return n; |
| 908 | default: |
| 909 | if (n < factorials.length) { |
| 910 | return factorials[n] / (factorials[k] * factorials[n - k]); |
| 911 | } else if (k >= biggestBinomials.length || n > biggestBinomials[k]) { |
| 912 | return Long.MAX_VALUE; |
| 913 | } |
| 914 | else if (k < biggestSimpleBinomials.length && n <= biggestSimpleBinomials[k]) { |
| 915 | // guaranteed not to overflow |
| 916 | long result = n--; |
| 917 | for (int i = 2; i <= k; n--, i++) { |
| 918 | result *= n; |
| 919 | result /= i; |
| 920 | } |
| 921 | return result; |
| 922 | } else { |
| 923 | int nBits = LongMath.log2(n, RoundingMode.CEILING); |
| 924 | long result = 1; |
| 925 | long numerator = n--; |
| 926 | long denominator = 1; |
| 927 | int numeratorBits = nBits; |
| 928 | // This is an upper bound on log2(numerator, ceiling). |
| 929 | |
| 930 | /* |
| 931 | * We want to do this in long math for speed, but want to avoid overflow. We adapt the |
| 932 | * technique previously used by BigIntegerMath: maintain separate numerator and |
| 933 | * denominator accumulators, multiplying the fraction into result when near overflow. |
| 934 | */ |
| 935 | for (int i = 2; i <= k; i++, n--) { |
| 936 | if (numeratorBits + nBits < Long.SIZE - 1) { |
| 937 | // It's definitely safe to multiply into numerator and denominator. |
| 938 | numerator *= n; |
| 939 | denominator *= i; |
| 940 | numeratorBits += nBits; |
| 941 | } else { |
| 942 | // It might not be safe to multiply into numerator and denominator, |
| 943 | // so multiply (numerator / denominator) into result. |
| 944 | result = multiplyFraction(result, numerator, denominator); |
| 945 | numerator = n; |
| 946 | denominator = i; |
| 947 | numeratorBits = nBits; |
| 948 | } |
| 949 | } |
| 950 | return multiplyFraction(result, numerator, denominator); |
| 951 | } |
| 952 | } |
| 953 | } |
no test coverage detected