refactor code
back to mutex as we no longer have read-only situations
This commit is contained in:
parent
0fe3ffaa59
commit
36fc8cf5c5
@ -1,5 +1,6 @@
|
|||||||
pub mod prime_utils {
|
pub mod prime_utils {
|
||||||
use num::{BigUint, One};
|
use num::{BigUint, One};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn log_2(x: &BigUint) -> u64 {
|
pub fn log_2(x: &BigUint) -> u64 {
|
||||||
@ -8,32 +9,31 @@ pub mod prime_utils {
|
|||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_prime(number: &BigUint) -> bool {
|
pub fn is_prime(number: &BigUint) -> bool {
|
||||||
if BigUint::one() == *number {
|
const ZERO: BigUint = BigUint::ZERO;
|
||||||
|
static TWO: Lazy<BigUint> = Lazy::new(|| BigUint::from(2u8));
|
||||||
|
|
||||||
|
if &BigUint::one() >= number {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if BigUint::from(4u8) > *number {
|
if &BigUint::from(4u8) > number {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if number % &*TWO == ZERO {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// number = 2^a - 1
|
// number = 2^a - 1
|
||||||
// a = log2(number + 1)
|
// a = log2(number + 1)
|
||||||
let a = log_2(&(number + 1u8));
|
let a = log_2(&(number + 1u8));
|
||||||
|
|
||||||
//if number isn't a mersenne number
|
//if number isn't a mersenne number
|
||||||
if BigUint::from(2u8).pow(a as u32) - BigUint::one() != *number {
|
if TWO.pow(a as u32) - BigUint::one() != *number {
|
||||||
const ZERO: BigUint = BigUint::ZERO;
|
|
||||||
let mut i = BigUint::one();
|
let mut i = BigUint::one();
|
||||||
let one = BigUint::one();
|
|
||||||
let two = &one + &one;
|
|
||||||
|
|
||||||
if number % &two == ZERO {
|
let sqrtnum = number.sqrt() + BigUint::one(); //fake ceil function
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let sqrtnum = number.sqrt() + one; //fake ceil function
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
i += &two; //we begin checking 3 and then continue with every second number as every even number is divisible by 2 and we already checked that
|
i += &*TWO; //we begin checking 3 and then continue with every second number as every even number is divisible by 2 and we already checked that
|
||||||
if number % &i == ZERO {
|
if number % &i == ZERO {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -44,14 +44,12 @@ pub mod prime_utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check if it's a mersenne prime
|
//check if it's a mersenne prime
|
||||||
// 4 12 194
|
|
||||||
let mut last = BigUint::from(4u8);
|
let mut last = BigUint::from(4u8);
|
||||||
let two = BigUint::from(2u8);
|
|
||||||
|
|
||||||
for _i in 2..a {
|
for _i in 2..a {
|
||||||
last = (last.pow(2) - &two) % number;
|
last = (last.pow(2) - &*TWO) % number;
|
||||||
}
|
}
|
||||||
|
|
||||||
last == BigUint::from(0u8)
|
last == BigUint::ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
src/main.rs
26
src/main.rs
@ -12,7 +12,7 @@ use std::{
|
|||||||
io::Write,
|
io::Write,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicU64, AtomicUsize},
|
atomic::{AtomicU64, AtomicUsize},
|
||||||
Arc, RwLock,
|
Arc, Mutex,
|
||||||
},
|
},
|
||||||
thread,
|
thread,
|
||||||
time::SystemTime,
|
time::SystemTime,
|
||||||
@ -67,7 +67,7 @@ fn worker(
|
|||||||
workloads: usize,
|
workloads: usize,
|
||||||
i: usize,
|
i: usize,
|
||||||
progress: &AtomicU64,
|
progress: &AtomicU64,
|
||||||
arcclone: &Arc<RwLock<Vec<BigUint>>>,
|
arcclone: &Arc<Mutex<Vec<BigUint>>>,
|
||||||
threads_done: &AtomicUsize,
|
threads_done: &AtomicUsize,
|
||||||
) {
|
) {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
@ -90,7 +90,7 @@ fn worker(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arcclone.write().unwrap().append(&mut primecache);
|
arcclone.lock().unwrap().append(&mut primecache);
|
||||||
|
|
||||||
threads_done.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
threads_done.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
@ -100,11 +100,11 @@ fn main() {
|
|||||||
if args.len() == 2 {
|
if args.len() == 2 {
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
let prime = args.nth(1).unwrap();
|
let prime = args.nth(1).unwrap();
|
||||||
|
let prime = BigUint::from_str(&prime).unwrap();
|
||||||
|
|
||||||
println!(
|
let is_prime = is_prime::prime_utils::is_prime(&prime);
|
||||||
"Number is prime: {}",
|
|
||||||
is_prime::prime_utils::is_prime(&BigUint::from_str(&prime).unwrap())
|
println!("Number is {}a prime", if is_prime { "" } else { "not " });
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -116,7 +116,7 @@ fn main() {
|
|||||||
let workloads = nthprime_approx / THREADS;
|
let workloads = nthprime_approx / THREADS;
|
||||||
|
|
||||||
let primecache: Vec<BigUint> = Vec::with_capacity(NU);
|
let primecache: Vec<BigUint> = Vec::with_capacity(NU);
|
||||||
let primemutex = std::sync::RwLock::new(primecache);
|
let primemutex = std::sync::Mutex::new(primecache);
|
||||||
let primearc = std::sync::Arc::new(primemutex);
|
let primearc = std::sync::Arc::new(primemutex);
|
||||||
|
|
||||||
let progress_val = AtomicU64::new(0);
|
let progress_val = AtomicU64::new(0);
|
||||||
@ -136,11 +136,13 @@ fn main() {
|
|||||||
let threads_completed = threads_done.load(std::sync::atomic::Ordering::Relaxed);
|
let threads_completed = threads_done.load(std::sync::atomic::Ordering::Relaxed);
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Progress: {}/{} ({:.0}%) | {}",
|
"Progress: {:0>width$}/{} ({:>3}%) | {:0>t_width$}",
|
||||||
n,
|
n,
|
||||||
N,
|
N,
|
||||||
n as f64 / NF * 100.0,
|
(n as f64 / NF * 100.0).min(100.0).floor(),
|
||||||
threads_completed
|
threads_completed,
|
||||||
|
width = N.to_string().len(),
|
||||||
|
t_width = THREADS.to_string().len()
|
||||||
);
|
);
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
|
||||||
@ -150,7 +152,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut primes = primearc.write().unwrap();
|
let mut primes = primearc.lock().unwrap();
|
||||||
primes.sort_unstable();
|
primes.sort_unstable();
|
||||||
|
|
||||||
#[allow(clippy::cast_possible_wrap)]
|
#[allow(clippy::cast_possible_wrap)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user