Right, so the "correct" solution would be to divide, and see if there is a remainder - use the modulo operator (%) to find the remainder [1] - by all primes up to SQRT(x)+1, where x is the "may be a prime" number.

A method that doesn't involve knowing which primes there are to know if this is a prime would be to check the remainder for 2 and then all odd numbers (3, 5, 7, ...) up to the square root of x. If you move the 2 check out of the loop, then it's a simple exercise to form a loop that checks all the odd values.

Use a separate "flag" variable to indicate if any of the tests failed (if so, you can quit checking, because it is not a prime).

After the loop, check the flag and print the appropriate message.

[1] Technically remainder and modulo are subtly different - but for the purposes here it's not important.

//An Implementation of sieve of Eratosthenes
#include <stdio.h>
#include <math.h>
#define N 300 //Upper Limit
void applysieve(int numbers[]){
int prime,i,j,count=0;
for(i=0;i<(sqrt(N)+1);i++){//Repeat the steps till the number is greater than the square root of the Upper Limit
if(numbers[i]!=0){ //Not Marked as zero,so prime
prime=numbers[i];
}
else{
continue; //Current number is not prime so need not find its multiples
}
/*find all the multiples of the current prime*/
for(j=i+1;j<N-1;j++){ //Repeat the steps for each number identified as prime
if(numbers[j]&#37;prime==0){ //find the multiples of the current prime
numbers[j]=0; //Mark as zero(Eliminate the multiple)
}
}
}
/* Print all the numbers that are not marked as zero */
printf("List of prime numbers\n");
for(i=0;i<N-1;i++){
if(numbers[i]!=0){
count++;
printf("%d\n",numbers[i]);
}
}
printf("Number of primes between 2 and 300 is %d",count);
}
int main(){
int numbers[N+1],i;
for(i=0;i<N-1;i++){
numbers[i]=i+2;
}
applysieve(numbers);
return 0;
}

11-26-2008

slingerland3g

Lol, much of the study of Sieve of Eratosthenes is how to make it fast and space efficient. The trick is to fill an array with 1's only. To save even more space use bits only. I have a working solution that is quite nice but most of the code is not my own. Please review Algorithms in C which mentions this code.

11-26-2008

stevesmithx

Quote:

Originally Posted by slingerland3g

Lol, much of the study of Sieve of Eratosthenes is how to make it fast and space efficient. The trick is to fill an array with 1's only. To save even more space use bits only. I have a working solution that is quite nice but most of the code is not my own. Please review Algorithms in C which mentions this code.

#define N 10000 //Codos to anyone that can explain why 100000 may segfault

You mean "kudos"...

QuantumPete

11-26-2008

matsp

I would have thought that 100000 would be OK, but a million will seg-fault because you run out of stack. If you make it a global (or static), or dynamically allocate the memory, you can make it muchos bigger.

--
Mats

11-26-2008

laserlight

Quote:

Originally Posted by slingerland3g

The trick is to fill an array with 1's only.

I believe that it is typically slightly easier to initialise the array with 0s instead. This would replace the first loop (or memset) in your example.

Quote:

Originally Posted by slingerland3g

Codos to anyone that can explain why 100000 may segfault

Stack size is rather limited.

By the way, main() normally returns an int, so state as such.

11-26-2008

stevesmithx

Quote:

Originally Posted by slingerland3g

Here is the books implementation:

#include <stdio.h>

#define N 10000 //Codos to anyone that can explain why 100000 may segfault

This uses several optimizations, namely it skips all even numbers, which cant be prime (except 2), and uses a fast method for finding the Root of the prime.

The code will tend to be slower than the Sieve of Eratosthenes for large primes (as it checks if a value is divisible by every odd value less than its square root). The benefit is that it uses less memory (the SoE relies on keeping track of all primes found for subsequent testing, and they have to be stored somewhere).

Modifying the value of Root through iteration (as the code does) is not necessarily fast: tracking of the value of Root from one iteration to the next is the optimisation. In comparison with the looping over all odd values, the benefit of that optimisation is minor.

There is the inconvenient fact that the code is also windows specific (relies on compiler extensions).