Reputation: 37
I am trying to create a Sieve of Eratosthenes in Java but the code I wrote seems to be flawed. I was wondering if anyone else can spot my mistake since I cannot. The output I get is simply [2], which means that my main loop doesn't work. I have only just started Java so I would appreciate it if you could give a detailed answer.
My code:
public static int[] primes(int n)
{
//Variable assignement
double sqrt;
List<Integer> primes= new ArrayList<Integer>();
//Adds 2 to primes so i don't need to include the even numbers in my for loop.
if(n>1)
{
primes.add(2);
}
//For loop that goes through the oneven numbers up to n
for(int counter1=3;counter1<=n;counter1+=2)
{
sqrt=Math.floor(Math.sqrt(0.0+counter1));
//for loop that tests if the first for loops number is prime
for(int counter2=0;sqrt<=primes.get(counter2);counter2++)
{
if(counter1 % primes.get(counter2) != 0 && counter2 ==sqrt)
{
primes.add(counter1);
}
if(counter1 % primes.get(counter2)==0)
{
break;
}
}
}
return convertIntegers(primes);
}
//Converts the list to an array
public static int[] convertIntegers(List<Integer> integers)
{
int[] ret = new int[integers.size()];
for (int i=0; i < ret.length; i++)
{
ret[i] = integers.get(i).intValue();
}
return ret;
}
Upvotes: 2
Views: 188
Reputation: 88727
I didn't throughly check your code but there might be a precision problem involved.
Note that double
might not represent integer values precisely thus counter2 ==sqrt
might be false even if sqrt
seems to be an integer.
To prevent this, try the following:
//this is not necessarily a square root anymore, btw :)
int sqrt = (int) Math.floor( Math.sqrt( (double)counter1 ) );
...
for( ... ) {
...
if(... && counter2 ==sqrt ) {
...
}
...
}
Edit:
A slightly more through analysis yields this:
Assume n = 5, thus the following steps would be executed in your code:
counter1 = 3
sqrt = 1
// floor(sqrt(2))counter2 = 0
counter1 % primes.get(counter2) != 0 && counter2 ==sqrt
is false since 3 % 2 = 1
BUT 0 != 1
counter1 % primes.get(counter2)==0
is false since 3 % 2 = 1
counter2 = 1
(next iteration)primes.get(counter2)
throws an exception since primes.get(1)
needs primes
to have at least 2 elements.What you might try is counter2 <=sqrt
instead.
Upvotes: 2
Reputation: 11638
if(counter1 % primes.get(counter2)==0);{
break;}
}
is unlikely to help matters. You have a semicolon before the opening brace - your break will always be executed.
Upvotes: 3