There is nothing really wrong with the initial code...
so whats the problem, well lets see
pow(2, 32) = 4294967296; //32 bit unsigned integer's maximum value + 1
pow(2, 64) = 18446744073709551616; //64 bit unsigned integer's max + 1
13! = 6,227,020,800 > 4,294,967,296 -- need something larger than 32 bits.
21! = 51,090,942,171,709,440,000 > 18,446,744,073,709,551,616 -- need more than 64 bits.
In general if we use Mathematica to evaluate the following:
CODE
In[1]:= Fbits[n_]:=N[Floor[Log[2, n!]] + 1]
In[2]:= Range[0, 32] //Fbits
Out[3]= {
1., 1., 2., 3., 5.,
7., 10., 13., 16.,
19., 22., 26., 29.,
33., 37., 41., 45.,
49., 53., 57., 62.,
66., 70., 75., 80.,
84., 89., 94., 98.,
103., 108., 113., 118.}
(
Sloans A072831)This tells us how many bits n! will require, n=13 requires 34 bits, and n = 32 requires 118 bits (just in case you want to know n=1024 requires 8770 bits or just over 1Kb).
i.e. The size of the factorial grows quite fast. You can use the double or long double to hold values past n = 12 (or 20), this actually works quite well since the number of trailing zeros increases so initially the error is actually kept quite small -- but of course the the divergence happens pretty fast as well and before too long the error compounds and the value diverges.
So what to do? Well you have to use an arbitrary precision library. or BigInteger library. There are many available on the web.
This post has been edited by NickDMax: 4 Aug, 2008 - 11:22 AM