public static double binomialCoefficientLog(final int n, final int k) {
		ArithmeticUtils.checkBinomial(n, k);
		if ((n == k) || (k == 0)) {
			return 0;
		}
		if ((k == 1) || (k == n - 1)) {
			return FastMath.log(n);
		}

		/*
		 * For values small enough to do exact integer computation, return the
		 * log of the exact value
		 */
		if (n < 67) {
			return FastMath.log(binomialCoefficient(n, k));
		}

		/*
		 * Return the log of binomialCoefficientDouble for values that will not
		 * overflow binomialCoefficientDouble
		 */
		if (n < 1030) {
			return FastMath.log(binomialCoefficientDouble(n, k));
		}

		if (k > n / 2) {
			return binomialCoefficientLog(n, n - k);
		}

		/*
		 * Sum logs for values that could overflow
		 */
		double logSum = 0;

		// n!/(n-k)!
		for (int i = n - k + 1; i <= n; i++) {
			logSum += FastMath.log(i);
		}

		// divide by k!
		for (int i = 2; i <= k; i++) {
			logSum -= FastMath.log(i);
		}

		return logSum;
	}