Search code examples
javaalgorithmmathfactorial

Getting factorial of a large number


Possible Duplicate:
Calculate the factorial of an arbitrarily large number, showing all the digits

This question might be asked thousand times here. I am repeating my question with a modification. I want to calculate factorial of a large number (max range of the number=10^6). Generally we uses a for loop from i=1 to i=number and every time multiplying the old value to the new value. This is fine for small numbers but what if i have a large number? The range of for loop is increased now. Java primitive data type int, long can't handle the resultant large number. They simply overflows. Although i knew about BigInteger class, which can handle this large output but still for loop is not suiting better here for me. Can somebody please suggest me any tick, any hack to calculate factorial of a number? Below is the simple program which works fine for small number-

public long getFactorial(long number) {
    long factorial = 1;
    for (long i = 1; i <= number; ++i) {
        factorial *= i;
    }
    return factorial;
}

Solution

  • Understand that the value is in the range of 105565708. It's going to take up about two megabytes of space, all by itself.

    That said, Guava's BigIntegerMath.factorial(int) is good enough to handle it, and more importantly, it's actually been optimized for large factorials -- it'll do significantly better than a straightforward for loop. (Disclosure: I contribute to Guava...and wrote much of BigIntegerMath.factorial myself.)

    That said, I wouldn't exactly call it fast -- my benchmarks indicate an average of 414ms for a factorial in that range -- but there isn't going to be a truly fast solution, not without extremely heavy-duty bignum libraries, and I wouldn't expect even those to be significantly faster.

    That's if you need the exact value. If you can settle for the logarithm, then yeah, either use Apache's logGamma(n+1) to get ln(n!), or approximate it yourself:

    double logFactorial = 0;
    for (int i = 2; i <= n; i++) {
      logFactorial += Math.log(i);
    }
    

    Some rounding error will probably accumulate, but it's supposed to be an approximation anyway.