Here's the whole code, which currently give correct results for input >= 7.
This line doesn't work yet:
if num < RES[0] { return ([2, 3, 5].iter().filter(|&p| p <= num).collect()) } else { return Vec<usize>::new() }
Here's the whole program, which works as shown for values >= 7.
extern crate integer_sqrt;
extern crate num_cpus;
extern crate rayon;
use integer_sqrt::IntegerSquareRoot;
use rayon::prelude::*;
use std::sync::atomic::{AtomicU8, Ordering};
use std::time::SystemTime;
fn print_time(title: &str, time: SystemTime) {
print!("{} = ", title);
println!("{} secs", {
match time.elapsed() {
Ok(e) => e.as_secs() as f64 + e.subsec_nanos() as f64 / 1_000_000_000f64,
Err(e) => { panic!("Timer error {:?}", e) },
}
});
}
fn atomic_slice(slice: &mut [u8]) -> &[AtomicU8] {
unsafe { &*(slice as *mut [u8] as *const [AtomicU8]) }
}
fn sozp5(num: usize) -> Vec<usize> {
let (md, rescnt) = (30, 8); // P5's modulus and residues count
static RES: [usize; 8] = [7,11,13,17,19,23,29,31];
static BITN: [u8; 30] = [0,0,0,0,0,1,0,0,0,2,0,4,0,0,0,8,0,16,0,0,0,32,0,0,0,0,0,64,0,128];
//if num < RES[0] { return ([2, 3, 5].iter().filter(|&p| p <= num).collect()) } else { return Vec<usize>::new() }
let kmax = (num - 2) / md + 1;
let mut prms = vec![0u8; kmax];
let sqrt_n = num.integer_sqrt();
let (mut modk, mut r, mut k) = (0,0,0);
loop {
if r == rescnt { r = 0; modk += md; k += 1 }
if (prms[k] & (1 << r)) != 0 { r += 1; continue }
let prm_r = RES[r];
let prime = modk + prm_r;
if prime > sqrt_n { break }
let prms_atomic = atomic_slice(&mut prms);
RES.par_iter().for_each (|ri| {
let prod = prm_r * ri - 2;
let bit_r = BITN[prod % md];
let mut kpm = k * (prime + ri) + prod/md;
while kpm < kmax { prms_atomic[kpm].fetch_or(bit_r, Ordering::Relaxed); kpm += prime; };
});
r += 1;
}
let mut primes: Vec<usize> = RES.par_iter().enumerate().flat_map_iter( |(i, ri)| {
prms.iter().enumerate().filter_map(move |(k, resgroup)| {
if resgroup & (1 << i) == 0 {
let prime = md * k + ri;
if prime <= num { return Some(prime) }
} None
}) }).collect();
primes.push(2); primes.push(3); primes.push(5);
primes
}
fn main() {
let mut val = String::new();
std::io::stdin().read_line(&mut val).expect("Failed to read line");
let mut substr_iter = val.split_whitespace();
let mut next_or_default = |def| -> usize {
substr_iter.next().unwrap_or(def).parse().expect("Input is not a number")
};
let num = next_or_default("0");
println!("threads = {}", num_cpus::get());
let ts = SystemTime::now();
let primes: Vec<usize> = sozp5(num);
print_time("total time", ts);
println!("total primes = {}", primes.len());
}