I tried to create a Java program to calculate the largest prime factor of any long number (in this case 600851475143). When I try to run it, the program compiles indefinitely, without producing warnings or a result. I understand there might be easier/more straightforward ways to solve this problem, but I'm curious on the reason why this one doesn't seem to work. I don't think the logic itself is wrong, a possible error might be my use of long variables (I have not used them often before).
I have declared some variables as long to allow them the space to be increased to a 'long' size
public class LargestPrimeFactor {
public static void main(String []args){
long num = 600851475143L;
long largestPrimeFactor = 0L;
boolean flag = false;
//Find all factors of num
for (long i = 2L; i <= num/2; i++){
//If a number i is a factor of num
if((num % i) == 0){
//Find if the factor i is a prime number (only divisible by 1 and by itself)
//by checking whether dividing it by any number results in an integer
for (long j = 2L; j <= i/2; j++){
if (i/j == 0){
flag = true;
}
if (!flag){
if (i > largestPrimeFactor){
largestPrimeFactor = i;
}
}
}
}
}
System.out.print(largestPrimeFactor);
}
}
Definitely, your code won't run infinitely. It's just that your code is not efficient and therefore it's taking too long to print the result. If you test with a smaller number or use an efficient code, you will get the result.
Given below is an efficient way of doing it:
public class Main {
public static void main(String[] args) {
long num = 600851475143L;
long divisor = 2, largestPrimeFactor;
while (num != 0) {
if (num % divisor != 0) {
divisor++;
} else {
largestPrimeFactor = num;
num /= divisor;
if (num == 1) {
System.out.println("The largest prime factor: " + largestPrimeFactor);
break;
}
}
}
}
}
Output:
The largest prime factor: 6857
Your code also has the following logical problems:
flag
has been declared outside the outer loop which means that it will never be reset to false
once it will become true
. i / j == 0
, you need to check i % j == 0
.break
the inner loop as soon as i % j == 0
. largestPrimeFactor
needs to be moved from the inner loop to the outer one.By the way, your test for primality is also not efficient. Instead of checking up to the half of the number, checking up to the square root of the number is sufficient. Check https://en.wikipedia.org/wiki/Primality_test for more details. Given below is an efficient code for primality test:
static boolean isPrime(int number) {
boolean prime = true;
if (number == 0 || number == 1 || number == -1)
return false;
for (int i = 2; i <= Math.sqrt(number); i++) {
if (number % i == 0) {
prime = false;
break;
}
}
return prime;
}