Factorial of Large numbers using Logarithmic identity

Given a very large number N, the task is to find the factorial of the number using Log.

Factorial of a non-negative integer is the multiplication of all integers smaller than or equal to N.

We have previously discussed a simple program to find the factorial in this article. Here, we will discuss an efficient way to find the factorial of large numbers.

Examples:

Input: N = 100
Output: 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000



Input: N = 50
Output: 30414093201713378043612608166064768844377641568960512000000000000

Approach: The most common iterative version runs in expected O(N) time. But as numbers become big it will be wrong to assume that multiplication takes constant time. The naive approach takes O(K*M) time for multiplication where K is the length of the multiplier and M is the length of the multiplicand. Therefore, the idea is to use logarithmic properties:

As we know that N! = \prod_{i=1}^{N} i and ln (ab) = ln(a) + ln(b)

Therefore:
ln (N!) = ln(}\prod_{i=1}^{N} i) = \sum_{i=1}^{N} ln(i)

Another property is
e^{ln(N!)} = N!
by substituting the value of ln(N!).

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to compute the
// factorial of big numbers
  
#include <bits/stdc++.h>
using namespace std;
  
// Maximum number of digits
// in output
#define MAX 1000
  
// Function to find the factorial
// of large number and return
// them in string format
string factorial(long long n)
{
    if (n > MAX) {
        cout << " Integer Overflow"
             << endl;
        return "";
    }
  
    long long counter;
    long double sum = 0;
  
    // Base case
    if (n == 0)
        return "1";
  
    // Calculate the sum of
    // logarithmic values
  
    for (counter = 1; counter <= n;
         counter++) {
        sum = sum + log(counter);
    }
  
    // Number becomes too big to hold in
    // unsigned long integers.
    // Hence converted to string
    // Answer is sometimes under
    // estimated due to floating point
    // operations so round() is used
    string result
        = to_string(round(exp(sum)));
  
    return result;
}
  
// Driver code
int main()
{
    clock_t tStart = clock();
    string str;
    str = factorial(100);
    cout << "The factorial is: "
         << str << endl;
  
    // Calculates the time taken
    // by the algorithm to execute
    cout << "Time taken: " << setprecision(10)
         << ((double)(clock() - tStart)
             / CLOCKS_PER_SEC)
         << " s" << endl;
}

chevron_right


Output:

The factorial is: 93326215443944231979346762015249956831505959550546075483971433508015162170687116519232751238036777284091181469944786448222582618323317549251483571058789842944.000000
Time taken: 0.000114 s

Time Complexity: O(N), where N is the given number.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up


If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.