primal_sieve/
sieve.rs

1use primal_bit::BitVec;
2use crate::wheel;
3use crate::streaming::StreamingSieve;
4
5use std::cmp;
6use std::slice;
7
8type SmallVec1<T> = ::smallvec::SmallVec<[T; 1]>;
9
10/// A heavily optimised prime sieve.
11///
12/// This stores information about primes up to some specified limit,
13/// allowing efficient queries of information about them. This caches
14/// the successive outputs of `StreamingSieve` and has very similar
15/// performance, modulo the differences in memory use: to cache the
16/// information `Sieve` uses approximately `limit / 30 +
17/// O(sqrt(limit))` bytes of memory. Consider directly using
18/// `StreamingSieve` if repeated queries are unnecessary, since that
19/// uses only `O(sqrt(limit))` bytes.
20///
21/// # Examples
22///
23/// ```rust
24/// let sieve = primal::Sieve::new(10_000_000);
25/// assert_eq!(sieve.prime_pi(123456), 11601);
26///
27/// assert!(sieve.is_prime(6395047));
28/// assert!(!sieve.is_prime(6395048));
29/// ```
30#[derive(Debug)]
31pub struct Sieve {
32    seg_bits: usize,
33    nbits: usize,
34    seen: SmallVec1<Item>,
35}
36
37#[derive(Debug)]
38struct Item {
39    count: usize,
40    bits: BitVec,
41}
42impl Item {
43    fn new(x: BitVec, so_far: &mut usize) -> Item {
44        *so_far += x.count_ones();
45        Item {
46            count: *so_far,
47            bits: x,
48        }
49    }
50}
51
52impl Sieve {
53    /// Create a new instance, sieving out all the primes up to
54    /// `limit`.
55    pub fn new(limit: usize) -> Sieve {
56        let mut seen = SmallVec1::new();
57        let mut nbits = 0;
58        let mut so_far = 0;
59        let mut seg_bits = None;
60        match wheel::small_for(limit) {
61            Some(bits) => {
62                nbits = bits.len();
63                seen.push(Item::new(bits, &mut 0));
64                seg_bits = Some(nbits)
65            }
66            None => {
67                let mut stream = StreamingSieve::new(limit);
68
69                while let Some((n, bits)) = stream.next() {
70                    let bits_limit = wheel::bit_index((limit - n).saturating_add(1)).1;
71                    seen.push(Item::new(bits.clone(), &mut so_far));
72                    nbits += cmp::min(bits.len(), bits_limit);
73                    match seg_bits {
74                        None => seg_bits = Some(bits.len()),
75                        Some(old) => assert_eq!(old, bits.len()),
76                    }
77                }
78            }
79        }
80        // this is a bit of a lie, but this length only matters when
81        // computing indices into `seen`, and everything will be in
82        // the first and only one in this case, so we better ensure
83        // that all queries get fed into that array (there's been
84        // panics from the limit being used as a query for
85        // e.g. prime_pi, as split_index would return (1, 0),
86        // suggesting that code look at a non-existant element of
87        // seen).
88        let seg_bits_adjust = if seen.len() == 1 { 1 } else { 0 };
89
90        Sieve {
91            seg_bits: seg_bits.unwrap() + seg_bits_adjust,
92            nbits,
93            seen,
94        }
95    }
96    fn split_index(&self, idx: usize) -> (usize, usize) {
97        (idx / self.seg_bits, idx % self.seg_bits)
98    }
99    fn index_for(&self, n: usize) -> (bool, usize, usize) {
100        let (b, idx) = wheel::bit_index(n);
101        let (base, tweak) = self.split_index(idx);
102        (b, base, tweak)
103    }
104
105    fn prime_pi_chunk(&self, n: usize) -> usize {
106        if n == 0 {
107            0
108        } else {
109            self.seen[n - 1].count
110        }
111    }
112    /// Return the largest number that this sieve knows about.
113    ///
114    /// It will be at least as large as the number passed to `new`,
115    /// but may be slightly larger.
116    ///
117    /// # Examples
118    ///
119    /// ```rust
120    /// let sieve = primal::Sieve::new(1000);
121    ///
122    /// assert!(sieve.upper_bound() >= 1000);
123    /// ```
124    pub fn upper_bound(&self) -> usize {
125        wheel::upper_bound(self.nbits)
126    }
127
128    /// Determine if `n` is a prime number.
129    ///
130    /// # Panics
131    ///
132    /// If `n` is out of range (greater than `self.upper_bound()`),
133    /// `is_prime` will panic.
134    ///
135    /// # Examples
136    ///
137    /// ```rust
138    /// let sieve = primal::Sieve::new(1000);
139    ///
140    /// assert_eq!(sieve.is_prime(0), false);
141    /// assert_eq!(sieve.is_prime(1), false);
142    /// assert_eq!(sieve.is_prime(2), true);
143    /// assert_eq!(sieve.is_prime(3), true);
144    /// assert_eq!(sieve.is_prime(4), false);
145    /// assert_eq!(sieve.is_prime(5), true);
146    ///
147    /// assert_eq!(sieve.is_prime(991), true);
148    /// assert_eq!(sieve.is_prime(993), false);
149    /// assert_eq!(sieve.is_prime(995), false);
150    /// assert_eq!(sieve.is_prime(997), true);
151    /// assert_eq!(sieve.is_prime(999), false);
152    /// ```
153    pub fn is_prime(&self, n: usize) -> bool {
154        match self.index_for(n) {
155            (false, _, _) => n == 2 || n == 3 || n == 5 || n == 7,
156            (true, base, tweak) => self.seen[base].bits[tweak],
157        }
158    }
159
160    /// Count the number of primes upto and including `n`.
161    ///
162    /// # Panics
163    ///
164    /// If `n` is out of range (greater than `self.upper_bound()`),
165    /// `prime_pi` will panic.
166    ///
167    /// # Examples
168    ///
169    /// ```rust
170    /// let sieve = primal::Sieve::new(1000);
171    ///
172    /// assert_eq!(sieve.prime_pi(10), 4);
173    /// // the endpoint is included
174    /// assert_eq!(sieve.prime_pi(11), 5);
175    ///
176    /// assert_eq!(sieve.prime_pi(100), 25);
177    /// assert_eq!(sieve.prime_pi(1000), 168);
178    /// ```
179    pub fn prime_pi(&self, n: usize) -> usize {
180        assert!(n <= self.upper_bound());
181        match n {
182            0..=1 => 0,
183            2 => 1,
184            3..=4 => 2,
185            5..=6 => 3,
186            7..=10 => 4,
187            _ => {
188                let (includes, base, tweak) = self.index_for(n);
189                let mut count = match wheel::BYTE_MODULO {
190                    30 => 3,
191                    _ => unimplemented!()
192                };
193
194                count += self.prime_pi_chunk(base);
195                count += self.seen[base].bits.count_ones_before(tweak + includes as usize);
196
197                count
198            }
199        }
200    }
201
202    /// Factorise `n` into (prime, exponent) pairs.
203    ///
204    /// Returns `Err((leftover, partial factorisation))` if `n` cannot
205    /// be fully factored, or if `n` is zero (`leftover == 0`). A
206    /// number can not be completely factored if and only if the prime
207    /// factors of `n` are too large for this sieve, that is, if there
208    /// is
209    ///
210    /// - a prime factor larger than `U^2`, or
211    /// - more than one prime factor between `U` and `U^2`
212    ///
213    /// where `U` is the upper bound of the primes stored in this
214    /// sieve.
215    ///
216    /// Notably, any number between `U` and `U^2` can always be fully
217    /// factored, since these numbers are guaranteed to only have zero
218    /// or one prime factors larger than `U`.
219    ///
220    /// # Examples
221    ///
222    /// ```rust
223    /// let sieve = primal::Sieve::new(100);
224    ///
225    /// assert_eq!(sieve.factor(2), Ok(vec![(2, 1)]));
226    /// assert_eq!(sieve.factor(4), Ok(vec![(2, 2)]));
227    /// assert_eq!(sieve.factor(1 << 31), Ok(vec![(2, 31)]));
228    ///
229    /// assert_eq!(sieve.factor(18), Ok(vec![(2, 1), (3, 2)]));
230    ///
231    /// assert_eq!(sieve.factor(25 * 81), Ok(vec![(3, 4), (5, 2)]));
232    ///
233    /// // "large" prime factors are OK, as long as there's only one
234    /// assert_eq!(sieve.factor(2 * 3 * 97 * 97 * 991),
235    ///            Ok(vec![(2, 1), (3, 1), (97, 2), (991, 1)]));
236    ///
237    /// // too many large factors is problematic
238    /// assert_eq!(sieve.factor(991 * 991),
239    ///            Err((991 * 991, vec![])));
240    /// assert_eq!(sieve.factor(2 * 3 * 17 * 17 * 991 * 991),
241    ///            Err((991 * 991, vec![(2, 1), (3, 1), (17, 2)])));
242    /// ```
243    pub fn factor(&self, mut n: usize) -> Result<Vec<(usize,usize)>,
244                                                 (usize, Vec<(usize, usize)>)>
245    {
246        if n == 0 { return Err((0, vec![])) }
247        if n == 1 { return Ok(vec![]) }
248
249        let mut ret = Vec::new();
250
251        // Using optimized internal iteration
252        self.primes_from(0).for_each_while(|p| {
253            if n % p == 0 {
254                n /= p;
255                let mut count = 1;
256                while n % p == 0 {
257                    n /= p;
258                    count += 1;
259                }
260                ret.push((p,count));
261            }
262
263            p.saturating_mul(p) < n
264        });
265
266        if n != 1 {
267            let b = self.upper_bound();
268            if let Some(bb) = b.checked_mul(b) {
269                if bb < n {
270                    // large factors :(
271                    return Err((n, ret))
272                }
273            }
274
275            // n is not divisible by anything from 1..=sqrt(n), so
276            // must be prime itself! (That is, even though we
277            // don't know this prime specifically, we can infer
278            // that it must be prime.)
279            ret.push((n, 1));
280        }
281        Ok(ret)
282    }
283
284    /// Compute *p<sub>n</sub>*, the `n` prime number, 1-indexed
285    /// (i.e. *p<sub>1</sub>* = 2, *p<sub>2</sub>* = 3).
286    ///
287    /// # Panics
288    ///
289    /// `n` must be larger than 0 and less than the total number of
290    /// primes in this sieve (that is,
291    /// `self.prime_pi(self.upper_bound())`).
292    ///
293    /// # Example
294    ///
295    /// ```rust
296    /// let (_, hi) = primal::estimate_nth_prime(1_000);
297    ///
298    /// let sieve = primal::Sieve::new(hi as usize);
299    ///
300    /// assert_eq!(sieve.nth_prime(10), 29);
301    /// assert_eq!(sieve.nth_prime(100), 541);
302    /// assert_eq!(sieve.nth_prime(1_000), 7919);
303    /// ```
304    pub fn nth_prime(&self, n: usize) -> usize {
305        match n {
306            1 => 2,
307            2 => 3,
308            3 => 5,
309            _ => {
310                assert!(0 < n && n <= 3 + self.prime_pi_chunk(self.seen.len()));
311                // the bit vectors don't store the first three primes,
312                // so we're looking for this (one-indexed) bit
313                let bit_n = n - 3;
314
315                let chunk_idx = self.seen.binary_search_by(|x| x.count.cmp(&bit_n))
316                                         .unwrap_or_else(|x| x);
317                let chunk_bits = self.prime_pi_chunk(chunk_idx);
318                let bit_idx = self.seen[chunk_idx].bits.find_nth_bit(bit_n - chunk_bits - 1);
319                wheel::from_bit_index(chunk_idx * self.seg_bits + bit_idx.unwrap())
320            }
321        }
322    }
323
324    /// Return an iterator over the primes from `n` (inclusive) to the
325    /// end of this sieve.
326    ///
327    /// NB. it is not guaranteed that the end is the same as the limit
328    /// passed to `new`: it may be larger. Consider using `take_while`
329    /// if the limit must be exact.
330    ///
331    /// # Panics
332    ///
333    /// If `n` is out of range (greater than `self.upper_bound()`),
334    /// `primes_from` will panic.
335    ///
336    /// # Examples
337    ///
338    /// ```rust
339    /// let sieve = primal::Sieve::new(1_000);
340    ///
341    /// // print the three digit primes
342    /// for p in sieve.primes_from(100).take_while(|x| *x < 1000) {
343    ///     println!("{}", p);
344    /// }
345    /// ```
346    pub fn primes_from(&self, n: usize) -> SievePrimes<'_> {
347        assert!(n <= self.upper_bound());
348        let early = match n {
349            0..=2 => Early::Two,
350            3 => Early::Three,
351            4..=5 => Early::Five,
352            _ => Early::Done
353        };
354        let (_, base, tweak) = self.index_for(n);
355        assert!(self.seen.len() == 1 || self.seg_bits % 8 == 0);
356        let base_byte_count = base * self.seg_bits / 8;
357
358        let bits = &self.seen[base].bits;
359
360        let current_base = base_byte_count * wheel::BYTE_MODULO;
361        let next_base = current_base.saturating_add(bits.len() * wheel::BYTE_MODULO / 8);
362
363        SievePrimes {
364            early,
365            base: current_base,
366            next_base,
367            ones: bits.ones_from(tweak),
368            limit: self.upper_bound(),
369            bits: self.seen[base + 1..].iter(),
370        }
371    }
372}
373
374#[derive(Clone)]
375enum Early {
376    Two,
377    Three,
378    Five,
379    Done,
380}
381
382/// An iterator over the primes stored in a `Sieve` instance.
383#[derive(Clone)]
384pub struct SievePrimes<'a> {
385    early: Early,
386    base: usize,
387    next_base: usize,
388    limit: usize,
389    ones: primal_bit::Ones<'a>,
390    bits: slice::Iter<'a, Item>,
391}
392
393impl<'a> SievePrimes<'a> {
394    #[inline]
395    fn from_bit_index(&self, i: usize) -> Option<usize> {
396        let w = wheel::from_bit_index(i);
397        match self.base.checked_add(w) {
398            Some(p) if p <= self.limit => Some(p),
399            _ => None,
400        }
401    }
402
403    fn advance_ones(&mut self) -> bool {
404        match self.bits.next() {
405            Some(Item { bits, .. }) => {
406                self.base = self.next_base;
407                self.next_base = self
408                    .next_base
409                    .saturating_add(bits.len() * wheel::BYTE_MODULO / 8);
410                self.ones = bits.ones_from(0);
411                true
412            },
413            None => false,
414        }
415    }
416
417    // Private method specifically to get internal iteration in `factor`.
418    // When `Try` is stable, we could more generally override `try_fold`, but
419    // that also requires keeping all state consistent, like `self.early`.
420    fn for_each_while<F>(mut self, mut f: F)
421    where
422        F: FnMut(usize) -> bool,
423    {
424        if !match self.early {
425            Early::Done => true,
426            Early::Two => f(2) && f(3) && f(5),
427            Early::Three => f(3) && f(5),
428            Early::Five => f(5),
429        } {
430            return;
431        }
432        loop {
433            while let Some(i) = self.ones.next() {
434                match self.from_bit_index(i) {
435                    Some(p) => if !f(p) { return },
436                    None => return,
437                }
438            }
439            if !self.advance_ones() {
440                return;
441            }
442        }
443    }
444}
445
446// See also `Iterator for Primes` with nearly identical code.
447impl<'a> Iterator for SievePrimes<'a> {
448    type Item = usize;
449
450    #[inline]
451    fn next(&mut self) -> Option<usize> {
452        match self.early {
453            Early::Done => {}
454            Early::Two => {
455                self.early = Early::Three;
456                return Some(2)
457            }
458            Early::Three => {
459                self.early = Early::Five;
460                return Some(3)
461            }
462            Early::Five => {
463                self.early = Early::Done;
464                return Some(5)
465            }
466        }
467        loop {
468            if let Some(i) = self.ones.next() {
469                return self.from_bit_index(i);
470            }
471            if !self.advance_ones() {
472                return None;
473            }
474        }
475    }
476
477    fn fold<Acc, F>(mut self, mut acc: Acc, mut f: F) -> Acc
478    where
479        F: FnMut(Acc, Self::Item) -> Acc
480    {
481        match self.early {
482            Early::Done => {}
483            Early::Two => {
484                acc = f(acc, 2);
485                acc = f(acc, 3);
486                acc = f(acc, 5);
487            }
488            Early::Three => {
489                acc = f(acc, 3);
490                acc = f(acc, 5);
491            }
492            Early::Five => {
493                acc = f(acc, 5);
494            }
495        }
496        loop {
497            while let Some(i) = self.ones.next() {
498                match self.from_bit_index(i) {
499                    Some(p) => acc = f(acc, p),
500                    None => return acc,
501                }
502            }
503            if !self.advance_ones() {
504                return acc;
505            }
506        }
507    }
508}
509
510#[cfg(test)]
511mod tests {
512    use primal_slowsieve::Primes;
513    use super::Sieve;
514
515    #[test]
516    fn small() {
517        let larger = Sieve::new(100_000);
518        for limit in 2..1_000 {
519            let sieve = Sieve::new(limit);
520            assert!(sieve.upper_bound() >= limit);
521            let primes = sieve.prime_pi(limit);
522            assert_eq!(primes, larger.prime_pi(limit));
523            let nth = sieve.nth_prime(primes);
524            assert!(nth <= limit);
525            assert_eq!(nth, larger.nth_prime(primes));
526        }
527    }
528
529    #[test]
530    fn is_prime() {
531        let limit = 2_000_000;
532        let real = Primes::sieve(limit);
533        let primes = Sieve::new(limit);
534
535        for i in 0..limit {
536            assert!(primes.is_prime(i) == real.is_prime(i),
537                    "failed for {} (real = {})", i, real.is_prime(i));
538        }
539    }
540
541    #[test]
542    fn primes_from_smoke() {
543        let limit = 100;
544        let primes = Sieve::new(limit);
545        let real = &[2, 3, 5, 7, 11,
546                     13, 17, 19, 23, 29,
547                     31, 37, 41, 43, 47,
548                     53, 59, 61, 67, 71,
549                     73, 79, 83, 89, 97];
550        for i in 0..limit {
551            let idx = real.iter().position(|x| *x >= i).unwrap_or(real.len());
552            assert_eq!(primes.primes_from(i).take_while(|x| *x <= limit).collect::<Vec<_>>(),
553                       &real[idx..]);
554        }
555    }
556    #[test]
557    fn primes_from_count() {
558        let limit = 2_100_000;
559        let primes = Sieve::new(limit);
560
561        let upto = 2_000_000;
562        assert_eq!(primes.primes_from(0).take_while(|x| *x <= upto).count(),
563                   primes.prime_pi(upto));
564    }
565    #[test]
566    fn primes_from_equality() {
567        let limit = 2_000_000;
568        let primes = Sieve::new(limit);
569        let real = Primes::sieve(limit);
570
571        let real = real.primes().take_while(|x| *x <= limit);
572        let computed = primes.primes_from(0).take_while(|x| *x <= limit);
573        let mut i = 0;
574        for (r, p) in real.zip(computed) {
575            assert_eq!(r, p);
576            i += 1;
577        }
578        assert_eq!(i, primes.prime_pi(limit));
579    }
580    #[test]
581    fn primes_from_no_overrun() {
582        let real = Sieve::new(1000);
583
584        for i in 0..100 {
585            let i = i * 38 / 39 + 1;
586            let sieve = Sieve::new(i);
587
588            for p in sieve.primes_from(0) {
589                assert!(real.is_prime(p));
590            }
591        }
592    }
593    #[test]
594    fn upper_bound() {
595        for i in 1..1000 {
596            let primes = Sieve::new(i);
597            assert!(primes.upper_bound() >= i);
598        }
599
600        let range = if cfg!(feature = "slow_tests") {
601            1..200
602        } else {
603            100..120
604        };
605        for i in range {
606            let i = i * 10_000;
607            let primes = Sieve::new(i);
608            assert!(primes.upper_bound() >= i);
609        }
610    }
611
612    #[test]
613    fn prime_pi() {
614        let (limit, mult) = if cfg!(feature = "slow_tests") {
615            (2_000_000, 19_998)
616        } else {
617            (200_000, 1_998)
618        };
619        let primes = Sieve::new(limit);
620        let real = Primes::sieve(limit);
621
622        for i in (0..20).chain((0..100).map(|n| n * mult + 1)) {
623            let val = primes.prime_pi(i);
624            let true_ = real.primes().take_while(|p| *p <= i).count();
625            assert!(val == true_, "failed for {}, true {}, computed {}",
626                    i, true_, val)
627        }
628    }
629
630    #[test]
631    fn factor() {
632        let primes = Sieve::new(1000);
633
634        let tests: &[(usize, &[(usize, usize)])] = &[
635            (1, &[]),
636            (2, &[(2_usize, 1)]),
637            (3, &[(3, 1)]),
638            (4, &[(2, 2)]),
639            (5, &[(5, 1)]),
640            (6, &[(2, 1), (3, 1)]),
641            (7, &[(7, 1)]),
642            (8, &[(2, 3)]),
643            (9, &[(3, 2)]),
644            (10, &[(2, 1), (5, 1)]),
645
646            (2*2*2*2*2 * 3*3*3*3*3, &[(2, 5), (3,5)]),
647            (2*3*5*7*11*13*17*19, &[(2,1), (3,1), (5,1), (7,1), (11,1), (13,1), (17,1), (19,1)]),
648            // a factor larger than that stored in the map
649            (7561, &[(7561, 1)]),
650            (2*7561, &[(2, 1), (7561, 1)]),
651            (4*5*7561, &[(2, 2), (5,1), (7561, 1)]),
652            ];
653        for &(n, expected) in tests.iter() {
654            assert_eq!(primes.factor(n), Ok(expected.to_vec()));
655        }
656    }
657
658    #[test]
659    fn factor_compare() {
660        let short = Sieve::new(30);
661        let long = Sieve::new(10000);
662
663        let short_lim = short.upper_bound() * short.upper_bound() + 1;
664
665        // every number less than bound^2 can be factored (since they
666        // always have a factor <= bound).
667        for n in 0..short_lim {
668            assert_eq!(short.factor(n), long.factor(n))
669        }
670        // larger numbers can only sometimes be factored
671        'next_n: for n in short_lim..10000 {
672            let possible = short.factor(n);
673            let real = long.factor(n).ok().unwrap();
674
675            let mut seen_small = None;
676            for (this_idx, &(p,i)) in real.iter().enumerate() {
677                let last_short_prime = if p >= short_lim {
678                    this_idx
679                } else if p > short.upper_bound() {
680                    match seen_small {
681                        Some(idx) => idx,
682                        None if i > 1 => this_idx,
683                        None => {
684                            // we can cope with one
685                            seen_small = Some(this_idx);
686                            continue
687                        }
688                    }
689                } else {
690                    // small enough
691                    continue
692                };
693
694                // break into the two parts
695                let (low, hi) = real.split_at(last_short_prime);
696                let leftover = hi.iter().fold(1, |x, &(p, i)| x * p.pow(i as u32));
697
698                assert_eq!(possible, Err((leftover, low.to_vec())));
699                continue 'next_n;
700            }
701
702            // if we're here, we know that everything should match
703            assert_eq!(possible, Ok(real))
704        }
705    }
706
707    #[test]
708    #[cfg_attr(not(feature = "slow_tests"), ignore)]
709    fn factor_overflow() {
710        // if bound^2 overflows usize, we can factor any usize,
711        // but must take care to not hit overflow assertions.
712
713        // set up a limit that would overflow if naively squared, and a
714        // prime greater than that limit.  (these are more than double)
715        #[cfg(target_pointer_width = "32")]
716        const LIMIT_PRIME: (usize, usize) = (0x10000, 0x2001d);
717        #[cfg(target_pointer_width = "64")]
718        const LIMIT_PRIME: (usize, usize) = (0x100000000, 0x200000011);
719
720        let (limit, prime) = LIMIT_PRIME;
721        let primes = Sieve::new(limit);
722        assert!(prime > primes.upper_bound());
723        assert_eq!(primes.factor(prime), Ok(vec![(prime, 1)]));
724    }
725
726    #[test]
727    fn factor_failures() {
728        let primes = Sieve::new(30);
729
730        assert_eq!(primes.factor(0),
731                   Err((0, vec![])));
732        // can only handle one large factor
733        assert_eq!(primes.factor(31 * 31),
734                   Err((31 * 31, vec![])));
735        assert_eq!(primes.factor(2 * 3 * 31 * 31),
736                   Err((31 * 31, vec![(2, 1), (3, 1)])));
737
738        // prime that's too large (bigger than 30*30).
739        assert_eq!(primes.factor(7561),
740                   Err((7561, vec![])));
741        assert_eq!(primes.factor(2 * 3 * 7561),
742                   Err((7561, vec![(2, 1), (3, 1)])));
743    }
744
745    #[test]
746    fn nth_prime() {
747        let primes = Sieve::new(2_000_000);
748
749        for (i, p) in primes.primes_from(0).enumerate() {
750            let n = i + 1;
751            if n < 2000 || n % 1000 == 0 {
752                assert_eq!(primes.nth_prime(n), p);
753            }
754        }
755        let total = primes.prime_pi(primes.upper_bound());
756        assert!(primes.nth_prime(total) <= primes.upper_bound());
757    }
758
759    #[test]
760    fn sum_primes() {
761        let primes = Sieve::new(2_000_000);
762
763        let mut manual_sum = 0u64;
764        for p in primes.primes_from(0) {
765            manual_sum += p as u64;
766        }
767        dbg!(manual_sum);
768
769        let folded_sum = primes.primes_from(0).fold(0u64, |acc, p| acc + p as u64);
770        let trait_sum = primes.primes_from(0).map(|p| p as u64).sum::<u64>();
771        assert_eq!(manual_sum, folded_sum);
772        assert_eq!(manual_sum, trait_sum);
773    }
774
775    #[test]
776    #[cfg_attr(not(feature = "slow_tests"), ignore)]
777    fn u32_primes() {
778        const COUNT: usize = 203_280_221; // number of 32-bit primes
779        const LAST: usize = 4_294_967_291; // last 32-bit prime
780        const SUM: u64 = 425_649_736_193_687_430; // sum of 32-bit primes
781
782        let sieve = Sieve::new(::std::u32::MAX as usize);
783        assert!(sieve.upper_bound() >= LAST);
784        assert_eq!(sieve.primes_from(LAST - 100).last(), Some(LAST));
785
786        let mut count = 0;
787        let mut sum = 0;
788        for p in sieve.primes_from(0) {
789            count += 1;
790            sum += p as u64;
791        }
792        assert_eq!(count, COUNT);
793        assert_eq!(sum, SUM);
794    }
795
796    #[test]
797    fn prime_pi_sieve_limit() {
798        // previously, these numbers would result in an index
799        // out-of-bounds when used as the limit and the number fed to
800        // prime_pi.
801        for limit in 19998..20004 {
802            let sieve = Sieve::new(limit);
803            sieve.prime_pi(limit);
804        }
805    }
806}