Here\'s my approach to factorials:
def factorial(n):
\'\'\'Returns factorial of n\'\'\'
r = 1
for i in range(1, n + 1):
r *= i
return
If you need a short execution time and don't need the best possible accuracy, you can use an approximation formula, e.g. Stirling approximation
You do realize that factorial(100000) is aproximately 2.8242294080×10^456,573
That's why it's slow, it's huge.
Factorials get very large, so it is often better to deal with logarithms of the number.
Many languages have an lgamma library function which computes the natural logarithm of the factorial of n-1.
This means that you can compute the natural logarithm of factorial(n) via lgamma(n+1).
You can divide by log10 to turn this into a base 10 logarithm.
So if you just want the number of digits, then this Python code will give the answer immediately:
from math import *
print ceil(lgamma(100000+1)/log(10))
You can use the reduce function rather than explicit looping thus:
>>> from functools import reduce
>>> mul = int.__mul__
>>> len(str(reduce(mul, range(2,100001), 1)))
456574
>>>
In Python 2 you need to use longs: long.__mul__
, and len(str(reduce(mul, range(2L,100001L), 1L)))
The slowdown in caused by a quadradic effect: as n gets larger you have to do more multiplications, but you also have to multiply larger numbers.
Finding a better algorithm won't be easy. You can try to exploit symmetries (as in FFT). It could also well pay to do multiplications in a different order, with intermediate results, such that you end up with multiplying only a few very big numbers at the end, but I haven't thought that to the end. In any case, you will have to find a law to exploit.
Look here for further inspiration.
If you just need an approximation, Ramanujan's factorial approximation is supposed to be more accurate than Stirling's.
If you need (or want) something precise, you might try GMP, the GNU Multiple Precision library. I've used it successfully for primality testing of large numbers in Python.