For a problem I'm working on, I need to calculate some very, very large factorials; or at least the first five non-zero digits of said factorial. I've worked out the function:
F(n) = ((n!)/(10S5(n)))%105
S5(n) = ec6eb4f9e17c320d12784365efaad220.png where p = 5 to get the trailing zeros of the factorial.
The Algorithm:
public static void main(String[] args) { // TODO Auto-generated method stub Timer t = new Timer();//just a timer, can be replaced with long start = System.currentTimeMillis(); t.start();//^ long fact = 1;//variable containing the needed value long limit = (long) 100000.0;//the nth factorial long pow10 = 10;//powers of 10 for(long i = 2; i <= limit; i++)//for loop to calculate the needed factorial { fact*=i; // (i-1)! * i = i! at that point while(fact%10==0)//does the fact/10^(s_5(i)) function to strip the trailing zeros fact/=10; fact %= 100000;// does the modulus to keep the numbers in bounds if(i%pow10==0)//simply prints out the factorial of powers of ten { pow10*=10; System.out.println(i + ": " + fact); } //System.out.println(i + ": " + fact); } System.out.println(fact);//print the result t.end();//ends the timer and prints out the result t.printElapsedTimeSeconds();//can be replaced with System.out.println("Elasped time: " + (System.currentTimeMillis()-start)/1000 + " seconds."); }
I can't use De Polignac's formula because the required sieve would take too much memory and brute forcing every prime takes too long. This is the output of F(1000000000):
10: 36288 100: 16864 1000: 53472 10000: 79008 100000: 2496 1000000: 4544 10000000: 51552 100000000: 52032 1000000000: 64704 64704 Elapsed time: 13.476 sec.
I need to calculcate F(1000000000000) or F of 1 trillion. This would take a very long time, there has to be some optimization or tweak that I'm missing somewhere.