0

I am trying to solve some project Euler problems and for whatever reason the following code gives me a division by zero error whenever I try to run it with large numbers. Can anyone tell me why?

import java.util.Scanner;

    public class Problem3LargestPrimeFactor {
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);

            System.out.println("Please enter the number to find the largest prime factor for.");
            long num = input.nextLong();
            int largest = 1;
            boolean isPrime = true;

            for(int i = 2; i < num; i++) {
                if(num % i == 0) {
                    for(int u = 2; u < i; u++){
                if(i % u == 0)
                    isPrime = false;
            }
            if(isPrime)
                largest = i;
            }
        }
    }
}

Now I'm aware that this is not the most efficient way to design the algorithm but can anyone tell me what is going on here?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 2
    "...with large numbers". Sounds like you're overflowing the capacity of `int`. – woz Dec 17 '13 at 21:05
  • 3
    `num` is a `long`, but `i` is only an `int`. So if `num` is bigger than the maximum integer, `i++` will eventually overflow. I guess it eventually reaches 0, whereupon `num % i` will raise a division by zero error. – Gareth Rees Dec 17 '13 at 21:06
  • thank you! I can't believe something so simple slipped my mind. –  Dec 17 '13 at 21:08
  • Have you seen this algorithm [sieve of eratosthenes](http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes) since you already know your limit may be useful – Felix Castor Dec 17 '13 at 21:09

2 Answers2

0

You're overflowing int. In the loop for(int i = 2; i < num; i++), num is a long and i is only an int. When i reaches it's capacity, it wraps around to -2,147,483,648 and keeps being incremented until it gets to 0, at which point you get your error.

woz
  • 10,888
  • 3
  • 34
  • 64
  • woz, I am using the code with numbers in the range of long and it is still giving me a division by zero error. –  Dec 17 '13 at 21:11
  • Even if you are in the range of a long, when you do `for(int i = 2; i < num; i++)`, `i` can get as big as `num`, and `i` is only an `int`. – woz Dec 17 '13 at 21:18
  • "any numbers larger than that could give you an error" -> Not necessarily, this would overflow back around to -2,147,483,648 and continue along all the way up until 0, at which it will error. – Sinkingpoint Dec 17 '13 at 21:19
0

Other responses have already pointed out your error. Let me give you a better algorithm for factoring a composite integer using trial division. The basic idea is to simply iterate through the possible factors, reducing n each time you find one. Here's pseudocode:

function factors(n)
    f, fs := 2, {}
    while f * f <= n
        while n % f == 0
            append f to fs
            n := n / f
        f := f + 1
    if n > 1
        append n to fs
    return fs

If you're interested in programming with prime numbers, I modestly recommend this essay at my blog.

user448810
  • 17,381
  • 4
  • 34
  • 59