0

I need to calculate running time of a factorial program with different sizes up to 130!. However, the program is currently using the long data type and that is not large enough to hold the outputs. After 20 factorial it turns negative and glitches out. How can I store even bigger numbers so I can calculate up to 130 factorial? Here are the methods doing the work:

public class FactorialCalculation {
    long startTime = System.nanoTime();

    //recursive Factorial method
    public long factorial(long number) {
        if (number <= 1)
            return 1;
        else
            return number * factorial(number - 1);
    }

    //Now output the factorials of 0 through 15
    public void displayFactorials() {
        // Calculate the factorial of o through 15
        for (int counter = 0; counter <= 130; counter++)
            System.out.print("Factorial of:" + counter + " " + factorial(counter) + " \n");

        long estimatedTime = System.nanoTime() - startTime;
        System.out.println(estimatedTime);

    } // end of the method displayFactorials


}  // end of class FactorialCalculation 

Here is the output showing it turning negative and then to 0.

Factorial of:0 1 
Factorial of:1 1 
Factorial of:2 2 
Factorial of:3 6 
Factorial of:4 24 
Factorial of:5 120 
Factorial of:6 720 
Factorial of:7 5040 
Factorial of:8 40320 
Factorial of:9 362880 
Factorial of:10 3628800 
Factorial of:11 39916800 
Factorial of:12 479001600 
Factorial of:13 6227020800 
Factorial of:14 87178291200 
Factorial of:15 1307674368000 
Factorial of:16 20922789888000 
Factorial of:17 355687428096000 
Factorial of:18 6402373705728000 
Factorial of:19 121645100408832000 
Factorial of:20 2432902008176640000 
Factorial of:21 -4249290049419214848 
Factorial of:22 -1250660718674968576 
Factorial of:23 8128291617894825984 
Factorial of:24 -7835185981329244160 
Factorial of:25 7034535277573963776 
Factorial of:26 -1569523520172457984 
Factorial of:27 -5483646897237262336 
Factorial of:28 -5968160532966932480 
Factorial of:29 -7055958792655077376 
Factorial of:30 -8764578968847253504 
Factorial of:31 4999213071378415616 
Factorial of:32 -6045878379276664832 
Factorial of:33 3400198294675128320 
Factorial of:34 4926277576697053184 
Factorial of:35 6399018521010896896 
Factorial of:36 9003737871877668864 
Factorial of:37 1096907932701818880 
Factorial of:38 4789013295250014208 
Factorial of:39 2304077777655037952 
Factorial of:40 -70609262346240000 
Factorial of:41 -2894979756195840000 
Factorial of:42 7538058755741581312 
Factorial of:43 -7904866829883932672 
Factorial of:44 2673996885588443136 
Factorial of:45 -8797348664486920192 
Factorial of:46 1150331055211806720 
Factorial of:47 -1274672626173739008 
Factorial of:48 -5844053835210817536 
Factorial of:49 8789267254022766592 
Factorial of:50 -3258495067890909184 
Factorial of:51 -162551799050403840 
Factorial of:52 -8452693550620999680 
Factorial of:53 -5270900413883744256 
Factorial of:54 -7927461244078915584 
Factorial of:55 6711489344688881664 
Factorial of:56 6908521828386340864 
Factorial of:57 6404118670120845312 
Factorial of:58 2504001392817995776 
Factorial of:59 162129586585337856 
Factorial of:60 -8718968878589280256 
Factorial of:61 3098476543630901248 
Factorial of:62 7638104968020361216 
Factorial of:63 1585267068834414592 
Factorial of:64 -9223372036854775808 
Factorial of:65 -9223372036854775808 
Factorial of:66 0 
Factorial of:67 0 
Factorial of:68 0 
Factorial of:69 0 
Factorial of:70 0 
Factorial of:71 0 
Factorial of:72 0 
Factorial of:73 0 
Factorial of:74 0 
Factorial of:75 0 
Factorial of:76 0 
Factorial of:77 0 
Factorial of:78 0 
Factorial of:79 0 
Factorial of:80 0 
Factorial of:81 0 
Factorial of:82 0 
Factorial of:83 0 
Factorial of:84 0 
Factorial of:85 0 
Factorial of:86 0 
Factorial of:87 0 
Factorial of:88 0 
Factorial of:89 0 
Factorial of:90 0 
Factorial of:91 0 
Factorial of:92 0 
Factorial of:93 0 
Factorial of:94 0 
Factorial of:95 0 
Factorial of:96 0 
Factorial of:97 0 
Factorial of:98 0 
Factorial of:99 0 
Factorial of:100 0 
Factorial of:101 0 
Factorial of:102 0 
Factorial of:103 0 
Factorial of:104 0 
Factorial of:105 0 
Factorial of:106 0 
Factorial of:107 0 
Factorial of:108 0 
Factorial of:109 0 
Factorial of:110 0 
Factorial of:111 0 
Factorial of:112 0 
Factorial of:113 0 
Factorial of:114 0 
Factorial of:115 0 
Factorial of:116 0 
Factorial of:117 0 
Factorial of:118 0 
Factorial of:119 0 
Factorial of:120 0 
Factorial of:121 0 
Factorial of:122 0 
Factorial of:123 0 
Factorial of:124 0 
Factorial of:125 0 
Factorial of:126 0 
Factorial of:127 0 
Factorial of:128 0 
Factorial of:129 0 
Factorial of:130 0 
Slava Vedenin
  • 58,326
  • 13
  • 40
  • 59
user3294617
  • 37
  • 1
  • 7
  • 1
    Can you try with [`BigInteger`](http://docs.oracle.com/javase/8/docs/api/java/math/BigInteger.html)? – Edwin Dalorzo Apr 21 '14 at 04:04
  • 2
    [BigInteger](http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html). Also, before posting a question here try google. Look what I find in the first link [here](https://www.google.com/search?q=Java+Data+Type+For+Large+Numbers&rlz=1C1KMZB_enUS562US562&oq=Java+Data+Type+For+Large+Numbers&aqs=chrome..69i57j69i60.1208j0j7&sourceid=chrome&es_sm=93&ie=UTF-8). – takendarkk Apr 21 '14 at 04:05
  • http://stackoverflow.com/questions/17394221/what-data-type-can-be-used-to-hold-the-value-of-the-factorial-of-100-000-000 – shin Apr 21 '14 at 04:09
  • @user2864740 Elaborate on why you think BigInteger would not work? – Edwin Dalorzo Apr 21 '14 at 04:11
  • No clue how many digits it is, but BigInteger will most certainly work for 130! if your system contains enough memory. That's the whole point of the class. – takendarkk Apr 21 '14 at 04:11
  • 1
    @Takendarkk But memory is finite, while [some algorithms grow *very* fast](http://en.wikipedia.org/wiki/Big_O_notation#Orders_of_common_functions).. – user2864740 Apr 21 '14 at 04:12
  • I have 12 gigs of memory on this machine. Could someone show how to use BigInteger in my code? It looks quite different than regular data types. – user3294617 Apr 21 '14 at 04:13
  • @user3294617 It's just an integer number type. The difference: you have to use the ugly methods it provides as there is no operator overloading. Good luck. – user2864740 Apr 21 '14 at 04:14
  • so just change long to BigInteger? – user3294617 Apr 21 '14 at 04:15
  • @Takendarkk Ahh, you're right in this case (130! ~ 6.4e^216), that's not as large as I thought (or really, about what I thought but still not as large as I thought it would be). – user2864740 Apr 21 '14 at 04:16
  • @vikeng21 I don't think introducing a decimal number into a factorial problem is the right way to go... – takendarkk Apr 21 '14 at 04:17
  • @Takendarkk thanks got it. will remove the comment – vikeng21 Apr 21 '14 at 04:21
  • I understand now but I'm having trouble implementing this properly. Could someone show me how with my current program? Then I can apply to it to my next one using loops. Thank you – user3294617 Apr 21 '14 at 04:30

3 Answers3

4

BigInteger will work just fine for this application.

If you read the javadoc, it is guaranteed* that BigInteger is capable of supporting numbers up to 2MAXINT; i.e. 22147483647. That is (very roughly) 7.9 * 10646456992.

130! is roughly 6.466855489220473e+219 or 6.46 * 10219. As you can see, this is miniscule in comparison with the largest value that is guaranteed representable.


* - Of course, this guarantee assumes that you have enough heap space. But we are talking about (MAXINT / 8 ) bytes ... 0.25 Gbytes ... which is not a huge amount on modern 64bit computers.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

Have a look at BigInteger. This can store very large values, size is not definitely known but since it is implemented as int[], it should be probably as explained in this question.

Community
  • 1
  • 1
anirudh
  • 4,116
  • 2
  • 20
  • 35
0

Look at the following code snippet, this will work for requirement.
You can achieve this by using BigInteger/BigDecimal instead of the long datatype.

long startTime = System.nanoTime();

public static void main(String[] args) {

    Test t  =   new Test();
    t.displayFactorials();
}


     //recursive Factorial method
public BigDecimal factorial(BigDecimal number)
{
      if (number.intValue()  <= 1)
    return BigDecimal.ONE;
      else
    return number.multiply( factorial ( number.subtract(BigDecimal.ONE) ) );
}

 //Now output the factorials of 0 through 15
public void displayFactorials()
{
        // Calculate the factorial of o through 15
           for ( int counter = 0; counter <= 130; counter++ )
               System.out.print ( "Factorial of:" + counter + " " + 
               factorial ( new BigDecimal(counter+"") ) + " \n");

         long estimatedTime = System.nanoTime() - startTime;
         System.out.println(estimatedTime);

} // end of the method displayFactorials

You can change the BigDecimal to BigInteger also.

Giri
  • 507
  • 6
  • 23