/// @param start      Sieve primes >= start.
/// @param stop       Sieve primes <= stop.
/// @param sieveSize  A sieve size in kilobytes.
/// @pre   start      >= 7
/// @pre   stop       <= 2^64 - 2^32 * 10
/// @pre   sieveSize  >= 1 && <= 2048
///
SieveOfEratosthenes::SieveOfEratosthenes(uint64_t start,
                                         uint64_t stop,
                                         uint_t sieveSize) :
  start_(start),
  stop_(stop),
  sieve_(NULL),
  preSieve_(NULL),
  eratSmall_(NULL),
  eratMedium_(NULL),
  eratBig_(NULL)
{
  if (start_ < 7)
    throw primesieve_error("SieveOfEratosthenes: start must be >= 7");
  if (start_ > stop_)
    throw primesieve_error("SieveOfEratosthenes: start must be <= stop");
  // choose the fastest pre-sieve limit
  limitPreSieve_ = config::PRESIEVE;
  if ((stop_ - start_) < config::PRESIEVE_THRESHOLD)
    limitPreSieve_ = 13;
  sqrtStop_ = static_cast<uint_t>(isqrt(stop_));
  // sieveSize_ must be a power of 2
  sieveSize_ = getInBetween(1u, floorPowerOf2(sieveSize), 2048u);
  sieveSize_ *= 1024; // convert to bytes
  segmentLow_ = start_ - getByteRemainder(start_);
  segmentHigh_ = segmentLow_ + sieveSize_ * NUMBERS_PER_BYTE + 1;
  // allocate the sieve of Eratosthenes array
  sieve_ = new byte_t[sieveSize_];
  init();
}
Ejemplo n.º 2
0
/// @param stop       Upper bound for sieving.
/// @param sieveSize  Sieve size in bytes.
/// @param limit      Sieving primes in EratMedium must be <= limit.
///
EratMedium::EratMedium(uint64_t stop, uint_t sieveSize, uint_t limit) :
  Modulo210Wheel_t(stop, sieveSize),
  limit_(limit)
{
  // ensure multipleIndex < 2^23 in crossOff()
  if (sieveSize > (1u << 21))
    throw primesieve_error("EratMedium: sieveSize must be <= 2^21, 2048 kilobytes");
  if (limit > sieveSize * 9)
    throw primesieve_error("EratMedium: limit must be <= sieveSize * 9");
  buckets_.push_back(Bucket());
}
Ejemplo n.º 3
0
    void pushBack_N_Primes(uint64_t n, uint64_t start)
    {
        n_ = n;
        PrimeSieve ps;
        std::size_t newSize = primes_.size() + static_cast<std::size_t>(n_);
        primes_.reserve(newSize);
        try
        {
            while (n_ > 0)
            {
                // choose stop > nth prime
                uint64_t logx = 50;
                uint64_t dist = n_ * logx + 10000;
                uint64_t stop = start + dist;

                // fix integer overflow
                if (stop < start)
                    stop = get_max_stop();

                ps.callbackPrimes(start, stop, this);
                start = stop + 1;

                if (stop >= get_max_stop())
                    throw primesieve_error("cannot generate primes > 2^64");
            }
        }
        catch (cancel_callback&) { }
    }
Ejemplo n.º 4
0
/// Set a stop number (upper bound) for sieving.
/// @pre stop <= 2^64 - 2^32 * 10
///
void PrimeSieve::setStop(uint64_t stop)
{
  uint64_t maxStop = PrimeFinder::getMaxStop();
  if (stop > maxStop)
    throw primesieve_error("stop must be <= " + PrimeFinder::getMaxStopString());
  stop_ = stop;
}
Ejemplo n.º 5
0
/// @param stop       Upper bound for sieving.
/// @param sieveSize  Sieve size in bytes.
/// @param limit      Sieving primes in EratSmall must be <= limit.
///
EratSmall::EratSmall(uint64_t stop, uint_t sieveSize, uint_t limit) :
  Modulo30Wheel_t(stop, sieveSize),
  limit_(limit)
{
  if (limit > sieveSize * 3)
    throw primesieve_error("EratSmall: limit must be <= sieveSize * 3");
  buckets_.push_back(Bucket());
}
Ejemplo n.º 6
0
/// PreSieve multiples of small primes <= limit.
/// @pre limit >= 11 && <= 23
///
PreSieve::PreSieve(int limit) :
  limit_(limit),
  preSieved_(NULL)
{
  // limit_ <= 23 prevents 32-bit overflows
  if (limit_ < 11 || limit_ > 23)
    throw primesieve_error("PreSieve: limit must be >= 11 && <= 23");
  init();
}
Ejemplo n.º 7
0
/// Massively parallel (unsynchronized) prime generation method for
/// use with ParallelPrimeSieve. 
///
void PrimeSieve::callbackPrimes_c(uint64_t start,
                                  uint64_t stop,
                                  void (*callback)(uint64_t, int))
{
  if (!callback)
    throw primesieve_error("callback is NULL");
  callback_tn_ = callback;
  flags_ = CALLBACK_PRIMES_C_TN;
  sieve(start, stop);
}
Ejemplo n.º 8
0
/// Massively parallel (unsynchronized) prime generation method for
/// use with ParallelPrimeSieve.
///
void PrimeSieve::callbackPrimes(uint64_t start,
                                uint64_t stop,
                                Callback<uint64_t, int>* cb)
{
  if (!cb)
    throw primesieve_error("Callback pointer is NULL");
  cb_tn_ = cb;
  flags_ = CALLBACK_PRIMES_OBJ_TN;
  sieve(start, stop);
}
Ejemplo n.º 9
0
/// @param stop       Upper bound for sieving.
/// @param sieveSize  Sieve size in bytes.
/// @param limit      Sieving primes in EratBig must be <= limit,
///                   usually limit = sqrt(stop).
///
EratBig::EratBig(uint64_t stop, uint_t sieveSize, uint_t limit) :
  Modulo210Wheel_t(stop, sieveSize),
  limit_(limit),
  log2SieveSize_(ilog2(sieveSize)),
  moduloSieveSize_(sieveSize - 1),
  stock_(NULL)
{
  // '>> log2SieveSize' requires a power of 2 sieveSize
  if (!isPowerOf2(sieveSize))
    throw primesieve_error("EratBig: sieveSize must be a power of 2");
  init(sieveSize);
}
Ejemplo n.º 10
0
void iterator::skipto(uint64_t start, uint64_t stop_hint)
{
  if (start > get_max_stop())
    throw primesieve_error("start must be <= " + PrimeFinder::getMaxStopString());

  start_ = start;
  stop_ = start;
  stop_hint_ = stop_hint;
  i_ = 0;
  last_idx_ = 0;
  tiny_cache_size_ = 1 << 11;
  primes_.clear();
}
Ejemplo n.º 11
0
void iterator::generate_previous_primes()
{
  primes_.clear();

  while (primes_.empty())
  {
    stop_ = subtract_underflow_safe(start_, 1);
    start_ = subtract_underflow_safe(stop_, get_interval_size(stop_));
    if (start_ <= stop_hint_ && stop_ >= stop_hint_)
      start_ = subtract_underflow_safe(stop_hint_, max_prime_gap(stop_hint_));
    primesieve::generate_primes(start_, stop_, &primes_);
    if (primes_.empty() && start_ < 2)
      throw primesieve_error("previous_prime(): smallest prime is 2");
  }

  last_idx_ = primes_.size() - 1;
  i_ = last_idx_;
}
Ejemplo n.º 12
0
void iterator::generate_next_primes()
{
  primes_.clear();

  while (primes_.empty())
  {
    start_ = add_overflow_safe(stop_, 1);
    stop_ = add_overflow_safe(start_, get_interval_size(start_));
    if (start_ <= stop_hint_ && stop_ >= stop_hint_)
      stop_ = add_overflow_safe(stop_hint_, max_prime_gap(stop_hint_));
    primesieve::generate_primes(start_, stop_, &primes_);
    if (primes_.empty() && stop_ >= get_max_stop())
      throw primesieve_error("next_prime() > " + PrimeFinder::getMaxStopString());
  }

  last_idx_ = primes_.size() - 1;
  i_ = 0;
}