1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
//! Simplistic and relatively unoptimised handling of basic //! tasks around primes: //! //! - checking for primality //! - enumerating primes //! - factorising numbers //! - estimating upper and lower bounds for π(*n*) (the number of primes //! below *n*) and *p<sub>k</sub>* (the <i>k</i>th prime) //! //! This uses a basic Sieve of Eratosthenes to enumerate the primes up to //! some fixed bound (in a relatively memory efficient manner), and then //! allows this cached information to be used for things like enumerating //! the primes, and factorisation via trial division. //! //! (Despite the name, it can sieve the primes up to 10<sup>9</sup> in //! about 5 seconds.) //! //! [*Source*](http://github.com/huonw/slow_primes) //! //! # Example //! //! Let's find the 10001st prime. The basic idea is to enumerate the //! primes and then take the 10001st in that list. //! //! Unfortunately, `Primes::sieve` takes an upper bound, and it gives //! us no information beyond this; so we really need some way to find //! an upper bound to be guaranteed to include the 10001st prime. If //! we had an a priori number we could just use that, but we don't //! (for the purposes of this example, anyway). Hence, we can either //! try filtering with exponentially larger upper bounds until we find //! one that works (e.g. doubling each time), or just take a shortcut //! and use deeper mathematics via //! [`estimate_nth_prime`](fn.estimate_nth_prime.html). //! //! ```rust //! // find our upper bound //! let (_lo, hi) = slow_primes::estimate_nth_prime(10001); //! //! // find the primes up to this upper bound //! let sieve = slow_primes::Primes::sieve(hi as usize); //! //! // (.nth is zero indexed.) //! match sieve.primes().nth(10001 - 1) { //! Some(p) => println!("The 10001st prime is {}", p), // 104743 //! None => unreachable!(), //! } //! ``` //! //! # Using this library //! //! Just add the following to your [`Cargo.toml`](http://crates.io/): //! //! ```toml //! [dependencies.slow_primes] //! git = "https://github.com/huonw/slow_primes" //! ``` #![cfg_attr(all(test, feature = "unstable"), feature(test, step_by))] extern crate num as num_; #[cfg(all(test, feature = "unstable"))] extern crate test; pub use estimate::{estimate_prime_pi, estimate_nth_prime}; //pub use fast_sieve::Sieve; pub use is_prime::{is_prime_miller_rabin}; pub use perfect_power::{as_perfect_power, as_prime_power}; pub use sieve::{Primes, PrimeIterator}; pub use fast_sieve::StreamingSieve; mod bit; mod estimate; mod fast_sieve; mod is_prime; mod perfect_power; mod sieve; #[allow(dead_code)] mod tables; /// (prime, exponent) pairs storing the prime factorisation of a /// number. pub type Factors = Vec<(usize, usize)>; #[cfg(all(test, feature = "unstable"))] mod benches { extern crate test; use super::{Primes, is_prime_miller_rabin}; use self::test::Bencher; const N: usize = 1_000_000; const STEP: usize = 101; #[bench] fn bench_miller_rabin_tests(b: &mut Bencher) { b.iter(|| { (1..N).step_by(STEP) .filter(|&n| is_prime_miller_rabin(n as u64)).count() }) } #[bench] fn bench_sieve_tests(b: &mut Bencher) { b.iter(|| { let sieve = Primes::sieve(1_000_000); (1..N).step_by(STEP) .filter(|&n| sieve.is_prime(n)).count() }) } }