CombinatoricsUtils { public static long factorial(final int n) throws NotPositiveException, MathArithmeticException { if (n < 0) { throw new NotPositiveException(LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER, n); } if (n > 20) { throw new MathArithmeticException(); } return FACTORIALS[n]; } private  CombinatoricsUtils(); static long binomialCoefficient(final int n, final int k); static double binomialCoefficientDouble(final int n, final int k); static double binomialCoefficientLog(final int n, final int k); static long factorial(final int n); static double factorialDouble(final int n); static double factorialLog(final int n); static long stirlingS2(final int n, final int k); static Iterator<int[]> combinationsIterator(int n, int k); static void checkBinomial(final int n,
                                     final int k);  }
@Test public void testFactorial() { for (int i = 1; i < 21; i++) { Assert.assertEquals(i + "! ", factorial(i), CombinatoricsUtils.factorial(i)); Assert.assertEquals(i + "! ", factorial(i), CombinatoricsUtils.factorialDouble(i), Double.MIN_VALUE); Assert.assertEquals(i + "! ", FastMath.log(factorial(i)), CombinatoricsUtils.factorialLog(i), 10E-12); } Assert.assertEquals("0", 1, CombinatoricsUtils.factorial(0)); Assert.assertEquals("0", 1.0d, CombinatoricsUtils.factorialDouble(0), 1E-14); Assert.assertEquals("0", 0.0d, CombinatoricsUtils.factorialLog(0), 1E-14); }