i came across the following program for calculating large factorials(numbers as big as 100).. can anyone explain me the basic idea used in this algorithm?? I need to know just the mathematics implemented in calculating the factorial.
#include <cmath> #include <iostream> #include <cstdlib> using namespace std; int main() { unsigned int d; unsigned char *a; unsigned int j, n, q, z, t; int i,arr[101],f; double p; cin>>n; p = 0.0; for(j = 2; j <= n; j++) p += log10(j); d = (int)p + 1; a = new unsigned char[d]; for (i = 1; i < d; i++) a[i] = 0; //initialize a[0] = 1; p = 0.0; for (j = 2; j <= n; j++) { q = 0; p += log10(j); z = (int)p + 1; for (i = 0; i <= z/*NUMDIGITS*/; i++) { t = (a[i] * j) + q; q = (t / 10); a[i] = (char)(t % 10); } } for( i = d -1; i >= 0; i--) cout << (int)a[i]; cout<<"\n"; delete []a; return 0; }
Algorithm of Factorial Program in C Read the integer and assign it to a variable. From the value of the integer up to 1, multiply each digit and update the final value. The final value at the end of all the multiplication till 1 is the factorial.
Using "BigInteger" we can calculate Factorial of large numbers easily . We can even calculate factorial of 10000 easily ....
Note that
n! = 2 * 3 * ... * n
so that
log(n!) = log(2 * 3 * ... * n) = log(2) + log(3) + ... + log(n)
This is important because if k
is a positive integer then the ceiling of log(k)
is the number of digits in the base-10 representation of k
. Thus, these lines of code are counting the number of digits in n!
.
p = 0.0; for(j = 2; j <= n; j++) p += log10(j); d = (int)p + 1;
Then, these lines of code allocate space to hold the digits of n!
:
a = new unsigned char[d]; for (i = 1; i < d; i++) a[i] = 0; //initialize
Then we just do the grade-school multiplication algorithm
p = 0.0; for (j = 2; j <= n; j++) { q = 0; p += log10(j); z = (int)p + 1; for (i = 0; i <= z/*NUMDIGITS*/; i++) { t = (a[i] * j) + q; q = (t / 10); a[i] = (char)(t % 10); } }
The outer loop is running from j
from 2
to n
because at each step we will multiply the current result represented by the digits in a
by j
. The inner loop is the grade-school multiplication algorithm wherein we multiply each digit by j
and carry the result into q
if necessary.
The p = 0.0
before the nested loop and the p += log10(j)
inside the loop just keep track of the number of digits in the answer so far.
Incidentally, I think there is a bug in this part of the program. The loop condition should be i < z
not i <= z
otherwise we will be writing past the end of a
when z == d
which will happen for sure when j == n
. Thus replace
for (i = 0; i <= z/*NUMDIGITS*/; i++)
by
for (i = 0; i < z/*NUMDIGITS*/; i++)
Then we just print out the digits
for( i = d -1; i >= 0; i--) cout << (int)a[i]; cout<<"\n";
and free the allocated memory
delete []a;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With