TravisTeague01
TravisTeague01

Reputation: 43

Why does the factorial past 20 not work in java when using a long?

I am creating a program that will find factorials using the long primitive type, only when doing the factorial for 21 it does not work. The answer it gives me -4249290049419214848 when the answer should be 5109094217000000000 and the max value for long is 9223372036854775807. I do not know why it will not give me 5109094217000000000 when that number is smaller than 9223372036854775807. Here is my code

long j = 1;
for(int i = 1; i <= 21; i++){
    j *= i;
}
System.out.println(j);

Upvotes: 1

Views: 1721

Answers (4)

Olli Puljula
Olli Puljula

Reputation: 2539

Long variable overflows.. 21! is 51090942171709440000 that is bigger than Long.MAX_VALUE

    long product = 1;
    for(int i = 1; i <= 21; i++){
        product = product * i;
        System.out.println(product);
        if(product < 0 ) {
            System.out.println("Overflow");
        }
    }

Upvotes: 0

Boann
Boann

Reputation: 50042

21! is not 5,109,094,217,000,000,000.

It is 51,090,942,171,709,440,000.

That is bigger than Long.MAX_VALUE, 9,223,372,036,854,775,807. Hence it overflows.

Upvotes: 1

Alexey Ayzin
Alexey Ayzin

Reputation: 209

An idea from: http://www.javawithus.com/programs/factorial-using-big-integer

Factorials greater than or equal to 21 create an overflow, so it's necessary to use something else. Big-Integer is ideal.

This is more or less the implementation:

import java.math.BigInteger;
import java.util.Scanner;

public class Factorial2 {

   public static void main(String[] args) {
       Scanner s = new Scanner(System.in);
       System.out.print("Enter a number: ");
       int n = s.nextInt();
       String fact = factorial(n);
       System.out.println("Factorial is " + fact);
   }

   public static String factorial(int n) {
       BigInteger fact = new BigInteger("1");
       for (int i = 1; i <= n; i++) {
           fact = fact.multiply(new BigInteger(i + ""));
       }
       return fact.toString();
   }
}

Upvotes: 0

Douglas Adams
Douglas Adams

Reputation: 1550

This may help:

long: The long data type is a 64-bit two's complement integer. The signed long has a minimum value of -263 and a maximum value of 263-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 264-1. Use this data type when you need a range of values wider than those provided by int. The Long class also contains methods like compareUnsigned, divideUnsigned etc to support arithmetic operations for unsigned long.

From: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

Upvotes: 0

Related Questions