I am trying to solve the problem using an array where I put the digits of n!
This is what I tried
int main()
{
int a[1000];
int n = 1;
a[0] = 1;
int limit = 100;
for (int i = 2; i <= limit; i++) {
int carry = 0;
for (int j = 0; j < n; j++) {
int prod = a[j] * i + carry;
a[j] = prod % 10;
carry = prod / 10;
if (carry) {
a[j + 1] = carry;
n = n + 1;
}
}
}
for (int i = (n - 1); i >= 0; i--)
printf("%d", a[i]);
return 0;
}
It works fine for 2! and 3! but for larger value of limit it just prints many random numbers.
For example, the output for 4! is 504.
The expected output is 24.
The problem is in the way you handle
carry: you should store the excess digits after finishing the loop over the existing digits. There can be more than 1 extra digit to store so you need a loop.Also note that you do not need
intfor the type of theaarray,charorunsigned charis sufficient.Here is a modified version that can handle numbers up to 3248 (less than 10001 digits).
Output:
For larger factorials, you can use the Stirling formula to approximate the number of decimal digits:
The number of decimal digits comes out as
number_of_digits(n!) ≈ log10(2π)/2 - n.log10(e) + (n+0.5).log10(n)
Here is a modified version, computing 9 digits at a time:
It can compute all digits of large factorials (as can be verified on the Factorial wikipedia page), but its time complexity could be improved using more advanced multiplications techniques, and binary computation leaving base 10 conversion for printing only.
This version is still quite simple and computes the 5565709 digits of 1000000! in 16mns on my M2 macbook air.