Serial Implementation

In our implementation, we have chosen to represent a range of numbers by an object which has the ability to count the number of primes in its range:

class CountPrimes {
public:
  CountPrimes(long start_, long stop_);
  long total();
private:
  long start;
  long stop;
  long count;
  bool counted;
  bool is_prime (long candidate);
};

CountPrimes::CountPrimes(long start_, long stop_):start(start_),stop(stop_),
						  count(0),counted(false){
  if (start>=stop)
    throw range_error("Start >= Stop");
}

bool CountPrimes::is_prime (long candidate){
  // special cases
  if (candidate<0) // negative
    return false;
  if (!candidate) // == 0?
    return false;
  if (candidate==1) // 1 is generally not considered prime
    return false;
  if (candidate==2)
    return true;
  // the general case
  for (long i=2; i<sqrt(candidate)+1; i++)
    if (!(candidate%i)) // does candidate divide evenly by i?
      return false;
  return true; // if we got this far, the number is prime
}

long CountPrimes::total(){
  if (counted) // only need to count once
    return count;
  for (long i=start; i<=stop; i++)
    if (is_prime(i))
      count++;
  counted=true; // now that we have counted, set flag to true
  return count;
}

We then use this object in a straightforward manner with the arguments presented on the command line:

int main (int argc, char *argv[]){
  if (argc<3)
    usage(argv[0]);

  try {
    CountPrimes counter(atol(argv[1]),atol(argv[2]));
    if (counter.total()>1)
      cout << "There were " << counter.total() << " primes." << endl;
    else
      cout << "There was " << counter.total() << " prime." << endl;
  }
  catch (range_error e){
    cout << "Exception: " << e.what() << endl;
    exit(EXIT_FAILURE);
  }
  return EXIT_SUCCESS;
}

The complete program can be found at ftp://ftp.cim.mcgill.ca/pub/people/ericb/primes.tar.bz2. Here is an example of compiling and using the program:

bash$ g++ -o primes primes.cpp
bash$ ./primes 0 10000
There were 1229 primes.