-3

This was part of my assignment and was asked to calculate factorial of 5 and 7.

I finished it as below:

 import java.util.Scanner;
    public class Factorial {
        public static void main(String [] args)
        {
            System.out.println("Please enter a number: ");
            Scanner input=new Scanner(System.in);
            int number=input.nextInt();
            int i,fact=1;  

              for(i=1;i<=number;i++){    
                  fact=fact*i;    
              }    
              System.out.println("Factorial of " + number + " is: " + fact);          
        }
    }

It worked for 5 and 7 (resulting 120 and 5040). But my professor came over and test it with 20 and 987654321, result returns -2102132736 and 0.

Why is that?

P.S. I thought for the case of 987654321, the result would crush the application or return error since it would be huge.

Meruemu
  • 611
  • 1
  • 8
  • 28
  • 4
    Integer overflow (no crash). Change `fact` to a `long` (or a `BigInteger`). – Elliott Frisch Oct 09 '16 at 03:30
  • I should probably use "Long" instead of "Int" if I know someone would use it with a big number. But still, why the result of factorial of 987654321 returns 0? – Meruemu Oct 09 '16 at 03:32
  • 1
    [Why does Java think that the product of all numbers from 10 to 99 is 0?](//stackoverflow.com/q/26375932) – Tom Oct 09 '16 at 03:33
  • 1
    U r using a int type data type, that will lose his range to multiple that much big number, use BigInteger data type instead of int – HAXM Oct 09 '16 at 03:33
  • @ElliottFrisch Yes, I noticed that now. I changed int to long and why the result of factorial of 987654321 returns 0? – Meruemu Oct 09 '16 at 03:37
  • @HAXM I changed int to long and why the result of factorial of 987654321 returns 0? – Meruemu Oct 09 '16 at 03:37
  • I'd also appreciate if someone can let me know why it's not an appropriate question (vote down). – Meruemu Oct 09 '16 at 03:40
  • 1
    @Meruemu Why are you asking them? Tom already linked the answer to why it is 0. The downvote may have come from how common this kind of question is, and how easy it would have been to find with simple research. – 4castle Oct 09 '16 at 03:41
  • @4castle Tom's link has the same problem (int overflows), since I said I have changed int to long, and the result returns 0 (not a negative number). I would think it's a different issue, and I wonder why. – Meruemu Oct 09 '16 at 03:46
  • Wait .. what? The linked answer(s) explain that `int` may return `0` if it overflows and you can't imagine, that the same can happen with `long`? Both types have their limits. – Tom Oct 09 '16 at 12:01

3 Answers3

2

This code can solve your problem . It is taken from here

class BigFactorial
{
    static void factorial(int n)
    {
        int res[] = new int[300];

        // Initialize result
        res[0] = 1;
        int res_size = 1;

        // Apply simple factorial formula n! = 1 * 2 * 3 * 4...*n
        for (int x=2; x<=n; x++)
            res_size = multiply(x, res, res_size);

        System.out.println("Factorial of given number is: ");
        for (int i=res_size-1; i>=0; i--)
            System.out.print(res[i]);
    }

    // This function multiplies x with the number represented by res[].
    // res_size is size of res[] or number of digits in the number represented
    // by res[]. This function uses simple school mathematics for multiplication.
    // This function may value of res_size and returns the new value of res_size
    static int multiply(int x, int res[], int res_size)
    {
        int carry = 0;  // Initialize carry

        // One by one multiply n with individual digits of res[]
        for (int i=0; i<res_size; i++)
        {
            int prod = res[i] * x + carry;
            res[i] = prod % 10;  // Store last digit of 'prod' in res[]
            carry  = prod/10;    // Put rest in carry
        }

        // Put carry in res and increase result size
        while (carry!=0)
        {
            res[res_size] = carry%10;
            carry = carry/10;
            res_size++;
        }
        return res_size;
    }

    // Driver program
    public static void main(String []args)
    {
        factorial(100);

    }

}
Community
  • 1
  • 1
Christopher Marlowe
  • 2,098
  • 6
  • 38
  • 68
1

Because 5040! is a very larger number (even long overflows). Use a BigInteger like

System.out.println("Please enter a number: ");
Scanner input = new Scanner(System.in);
int number = input.nextInt();
BigInteger fact = BigInteger.ONE;
for (int i = 2; i <= number; i++) { // <-- x * 1 = x
    fact = fact.multiply(BigInteger.valueOf(i));
}
System.out.println("Factorial of " + number + " is: " + fact);
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • Can you get the result of factorial of 987654321? –  Oct 09 '16 at 03:46
  • @saka yes. It's just very very large. – Elliott Frisch Oct 09 '16 at 03:47
  • 1
    This algorithm has the ability to handle large numbers, but it's very inefficient in terms of speed. Better use [a smarter algorithm](http://www.luschny.de/math/factorial/FastFactorialFunctions.htm). – 4castle Oct 09 '16 at 03:47
  • I am using eclipse and it returns 0 for factorial of 987654321. Could it be due to different environment? – Meruemu Oct 09 '16 at 03:49
1

This is because of the fact that the container that you have taken for storing and printing your result does not have the capacity to hold such big integer (I mean factorial of 20). So, you need a bigger container. As others already suggested, you can use BIGINTEGER.