Here is my code:
public class LargestPrimeFactor {
/**
* @param args the command line arguments
*/
public static boolean isPrime(long x){
for (int y=2; y<x; y++){
if (x%y==0){
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println("Find out the largest prime factor of 600851475143");
long num=600851475143L;
int largest=0;
int y=0;
for (int x=2; x<num; x++){
if (num%x==0&&isPrime(x)==true){
System.out.println(x);
}
}
System.out.println(largest);
}
Here is the output:
Find out the largest prime factor of 600851475143
71
839
1471
6857
-716151937
-408464633
-87625999
-10086647
-5753023
-1234169
-486847
-104441
-59569
-6857
-1471
-839
-71
-1
Exception in thread "main" java.lang.ArithmeticException: / by zero
at largestprimefactor.LargestPrimeFactor.main(LargestPrimeFactor.java:32)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 minutes 10 seconds)
How do I print out the largest number? and why does the output show negative numbers when "x" is supposed to be constantly increasing, never decreasing?
Here is my edited code:
public static boolean isPrime(long x){
for (int y=2; y<x; y++){
if (x%y==0){
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println("Find out the largest prime factor of 600851475143");
long num=600851475143L;
long largest=0;
int y=0;
for (long x=2; x<num/2; x++){
if (num%x==0&&isPrime(x)==true){
System.out.println(x);
if (largest<x){
largest=x;
}
}
}
System.out.println(largest);
}
Here is the new output
Find out the largest prime factor of 600851475143
71
839
1471
6857
0
BUILD SUCCESSFUL (total time: 318 minutes 31 seconds)
How do I get the final answer to be printed out as "6857" rather than "0"? Also, if you notice, the run time for the program was a little over 5 hours. How do I speed up this process?
You are using an int
for the for
loop, which is overflowing. Use a long variable to iterate.
for (int x=2; x<num; x++){
^^^
The reason for the negative values is that it is wrapping around. If you want to find just the largest, you could use a new long
variable to store the max-seen so far. Another way is to simply iterate over the range in reverse .
Additionally, you can shorten your loop to just check till the square root of the given number. If you find a factor, you can do (num / ans)
to find the larger factor.
You can speed up the process significantly with a few tricks:
(x % factor == 0L)
check, which is a much, much faster check than isPrime(factor)
. The following code combines these ideas and finds the answer in about a tenth of a second:
public final class Euler3 {
// Modified from https://optimi.wordpress.com/2010/12/02/how-to-compute-64-bit-integer-square-roots-very-quickly/
public static final long floorSqrt(final long x) {
if (x < 0L) throw new IllegalArgumentException("Cannot take the square root of a negative number");
if ((x & 0xfff0000000000000L) == 0L) return (long) StrictMath.sqrt(x);
final long result = (long) StrictMath.sqrt(2.0d*(x >>> 1));
return result*result - x > 0L ? result - 1L : result;
}
public static final long biggestPrimeFactor(long x) {
// Properly handle zero.
if (x == 0L) return 0L;
// Properly handle negative numbers.
if (x < 0L) x = -x;
long lastPrimeRemoved = 1L;
long sqrtX = floorSqrt(x);
// Handle the prime factor 2.
// (x & 1L) == 0L is true whenever the number is even.
// x >>>= 1 replaces x with x divided by 2 if x is positive.
// >>>= is used because the minimum long can't be negated above.
if ((x & 1L) == 0L) {
x >>>= 1;
while ((x & 1L) == 0L) x >>>= 1;
lastPrimeRemoved = 2L;
sqrtX = floorSqrt(x);
}
// Handle the odd prime factors.
for (long factor = 3L; (x != 1L) && (sqrtX >= factor); factor += 2L) {
if (x % factor == 0L) {
x /= factor;
while (x % factor == 0L) x /= factor;
lastPrimeRemoved = factor;
sqrtX = floorSqrt(x);
}
}
// If we removed all the prime factors, return the last one we removed.
if (x == 1L) return lastPrimeRemoved;
// Otherwise, whatever remains is itself a large prime. Return that.
else return x;
}
public static final void main(final String[] args) {
System.out.println(biggestPrimeFactor(600851475143L));
}
}
A possible solution is to use recursion as shown below:
public class PrimeFactor{
public static void main(String[] args){
long n = 600851475143L;
System.out.println("LARGEST = "+largestPrime(2,n));
}
public static long largestPrime(long f, long val){
if (val == f){
return f;
}
else if (val % f ==0)
{
return largestPrime(f, val/f);
}
else
{
return largestPrime(f+1, val);
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.