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: 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000Input: 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
// 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;
} |
// Java program to compute the // factorial of big numbers import java.math.BigDecimal;
import java.math.RoundingMode;
public class Factorial {
// Maximum number of digits // in output static int MAX = 1000 ;
// Function to find the factorial // of large number and return // them in string format static String factorial( int n) {
if (n > MAX) {
System.out.println( " Integer Overflow" );
return "" ;
}
int counter;
double sum = 0 ;
// Base case
if (n == 0 )
return "1" ;
// Calculate the sum of
// logarithmic values
for (counter = 1 ; counter <= n; counter++) {
sum = sum + Math.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
BigDecimal result = new BigDecimal(Math.exp(sum));
result = result.setScale( 0 , RoundingMode.HALF_UP);
return result.toString();
}
// Driver code
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
String str;
str = factorial( 100 );
System.out.println( "The factorial is: " + str);
// Calculates the time taken
// by the algorithm to execute
System.out.println( "Time taken: " + (System.currentTimeMillis() - startTime) + " ms" );
}
} // This code is contributed by Aman Kumar. |
# Python program to compute the # factorial of big numbers import math
import time
# Maximum number of digits # in output MAX = 1000
# Function to find the factorial # of large number and return # them in string format def factorial(n):
if (n > MAX ):
print ( " Integer Overflow" )
return ""
counter = 0
sum = 0
# Base case
if (n = = 0 ):
return "1"
# Calculate the sum of
# logarithmic values
for counter in range ( 1 ,n + 1 ):
sum = sum + math.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
result = str ( round (math.exp( sum )))
return result
# Driver code tStart = time.perf_counter()
str = factorial( 100 )
print ( "The factorial is: " ,end = "")
print ( str )
# Calculates the time taken # by the algorithm to execute tEnd = time.perf_counter()
print ( "Time taken: " ,end = "")
print ( '%.10f' % (tEnd - tStart),end = "")
print ( " s" )
# This code is contributed by Pushpesh Raj. |
// Javascript program to compute the // factorial of big numbers // Function to find the factorial // of large number and return // them in string format function factorial(n) {
const MAX = 1000;
if (n > MAX) {
console.log( " Integer Overflow" );
return "" ;
}
let counter;
let sum = 0;
// Base case
if (n === 0)
return "1" ;
// Calculate the sum of
// logarithmic values
for (counter = 1; counter <= n; counter++) {
sum = sum + Math.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
const result = BigInt(Math.round(Math.exp(sum))).toString();
return result;
} // Driver code const startTime = Date.now(); let str; str = factorial(100); console.log( "The factorial is: " + str);
// Calculates the time taken // by the algorithm to execute console.log( "Time taken: " + (Date.now() - startTime) + " ms" );
|
using System;
using System.Diagnostics;
using System.Numerics;
public class Factorial {
const int MAX = 1000;
static string ComputeFactorial( long n) {
if (n > MAX) {
Console.WriteLine( " Integer Overflow" );
return "" ;
}
long counter;
double sum = 0;
if (n == 0)
return "1" ;
for (counter = 1; counter <= n; counter++) {
sum = sum + Math.Log(counter);
}
string result = BigInteger.Exp(sum).ToString();
return result;
}
static void Main( string [] args) {
Stopwatch stopwatch = Stopwatch.StartNew();
string str;
str = ComputeFactorial(100);
Console.WriteLine( "The factorial is: " + str);
Console.WriteLine( "Time taken: " + stopwatch.Elapsed.TotalSeconds.ToString( "0.000000" ) + " s" );
}
} |
Output
The factorial is: 93326215443944231979346762015249956831505959550546075483971433508015162170687116519232751238036777284091181469944786448222582618323317549251483571058789842944.000000 Time taken: 0.000198 s
Time Complexity: O(N), where N is the given number.
Auxiliary Space: O(1) since using constant variables