Inspired by two of the earlier posts, I offer this implementation and unit test case. While testing if the BigInteger class could compute and represent a factorial where n=Integer.MAX_INT, I realize this method does not return large order factorial quickly. If the user of the method needed to know the values of several large order factorials, then a better implementation would use precomputed results for all values of n and probably require database.

package com.example.math;

import java.math.BigInteger;

**public** **class** Functions {

**private** **static** **long**[] smallFactorialResults =

{

1,

1,

2,

6,

24,

120,

720,

5040,

40320,

362880,

3628800,

39916800,

479001600,

6227020800L,

87178291200L,

1307674368000L,

20922789888000L,

355687428096000L,

6402373705728000L,

121645100408832000L,

2432902008176640000L // n == 20

};

**public** **static** BigInteger factorial(**int** n)

{

**final** BigInteger result;

// validate argument

**if** ( n < 0 )

{

**throw** **new** IllegalArgumentException("cannot compute a factorial less than zero. n = " + n +

"not allowed");

}

// avoid cost of BigInteger Math if the result can fit in a long

**else** **if** ( n < smallFactorialResults.length)

{

result = BigInteger.valueOf(smallFactorialResults[n]);

}

**else**

{

BigInteger product = BigInteger.valueOf(smallFactorialResults[smallFactorialResults.length-1]);

**for** (**int** i = smallFactorialResults.length; i <= n; i++)

{

product = product.multiply(BigInteger.valueOf(i));

}

result = product;

}

**return** result;

}

}

package com.example.math;

import java.math.BigInteger;

import junit.framework.TestCase;

**public** **class** FucntionsTest **extends** TestCase {

**public** **void** testFactorial() {

BigInteger result = BigInteger.ONE;

**try**

{

result = Functions.factorial(-1);

}

**catch** (IllegalArgumentException ex)

{

assertTrue(true);

}

**catch** (Exception ex)

{

assertTrue(false);

}

assertEquals(result,BigInteger.ONE);

// simple on array look ups

assertEquals(BigInteger.valueOf(1),Functions.factorial(0));

assertEquals(BigInteger.valueOf(1),Functions.factorial(1));

assertEquals(BigInteger.valueOf(120),Functions.factorial(5));

// test boundary condition between lookups and big integer math

result = Functions.factorial(20);

assertEquals(BigInteger.valueOf(2432902008176640000L),result);

result = result.multiply(BigInteger.valueOf(21));

assertEquals(result,Functions.factorial(21));

// test more than one iteration on the loop.

result = result.multiply(BigInteger.valueOf(22));

assertEquals(result,Functions.factorial(22));

}

**public** **void** testForMaxFactorial()

{

// prove that argument n has no upper bound if typed as an integer

BigInteger result = BigInteger.ONE;

result = Functions.factorial(Integer.MAX_VALUE);

assertFalse(result.equals(BigInteger.ONE));

}

}

I'll reply to this post with the result of the testForMaxFactorial method when it completes.