refactor code
This commit is contained in:
parent
f6200bc99a
commit
90069e9ab4
@ -2,6 +2,7 @@
|
||||
name = "isprime"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
default-run = "isprime"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@ -42,4 +43,7 @@ str_to_string = "deny"
|
||||
cast_possible_truncation = "allow"
|
||||
cast_precision_loss = "allow"
|
||||
cast_sign_loss = "allow"
|
||||
missing_errors_doc = "allow"
|
||||
missing_errors_doc = "allow"
|
||||
|
||||
[[bin]]
|
||||
name = "isprime"
|
@ -7,49 +7,70 @@ pub mod prime_utils {
|
||||
x.bits() - 1
|
||||
}
|
||||
|
||||
static FOUR: Lazy<BigUint> = Lazy::new(|| BigUint::from(4u8));
|
||||
static TWO: Lazy<BigUint> = Lazy::new(|| BigUint::from(2u8));
|
||||
static ONE: Lazy<BigUint> = Lazy::new(BigUint::one);
|
||||
const ZERO: BigUint = BigUint::ZERO;
|
||||
|
||||
#[must_use]
|
||||
pub fn is_prime(number: &BigUint) -> bool {
|
||||
const ZERO: BigUint = BigUint::ZERO;
|
||||
static TWO: Lazy<BigUint> = Lazy::new(|| BigUint::from(2u8));
|
||||
|
||||
if &BigUint::one() >= number {
|
||||
if &*ONE >= number {
|
||||
return false;
|
||||
}
|
||||
if &BigUint::from(4u8) > number {
|
||||
if &*FOUR > number {
|
||||
return true;
|
||||
}
|
||||
if number % &*TWO == ZERO {
|
||||
if !number.bit(0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// number = 2^a - 1
|
||||
// mersenne numbers = 2^a - 1
|
||||
// a = log2(number + 1)
|
||||
let a = log_2(&(number + 1u8));
|
||||
|
||||
//if number isn't a mersenne number
|
||||
if TWO.pow(a as u32) - BigUint::one() != *number {
|
||||
let mut i = BigUint::one();
|
||||
let is_mersenne = {
|
||||
let num_p2 = {
|
||||
let mut num = BigUint::default();
|
||||
num.set_bit(a, true);
|
||||
num
|
||||
};
|
||||
assert!(num_p2 > BigUint::one());
|
||||
|
||||
let sqrtnum = number.sqrt() + BigUint::one(); //fake ceil function
|
||||
let num_p2 = num_p2 - &*ONE;
|
||||
|
||||
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
|
||||
if number % &i == ZERO {
|
||||
return false;
|
||||
}
|
||||
if i >= sqrtnum {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
&num_p2 == number
|
||||
};
|
||||
|
||||
if is_mersenne {
|
||||
return mersenne_check(number, a);
|
||||
}
|
||||
|
||||
//check if it's a mersenne prime
|
||||
let mut last = BigUint::from(4u8);
|
||||
let sqrtnum = number.sqrt() + &*ONE; //fake ceil function
|
||||
|
||||
for _i in 2..a {
|
||||
inner_prime(number, &sqrtnum)
|
||||
}
|
||||
|
||||
fn mersenne_check(number: &BigUint, a: u64) -> bool {
|
||||
let mut last = FOUR.clone();
|
||||
|
||||
for _ in 2..a {
|
||||
last = (last.pow(2) - &*TWO) % number;
|
||||
}
|
||||
|
||||
last == BigUint::ZERO
|
||||
last == ZERO
|
||||
}
|
||||
|
||||
fn inner_prime(number: &BigUint, sqrtnum: &BigUint) -> bool {
|
||||
let mut i = BigUint::one();
|
||||
|
||||
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
|
||||
if &i >= sqrtnum {
|
||||
return true;
|
||||
}
|
||||
if number % &i == ZERO {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
36
src/main.rs
36
src/main.rs
@ -13,7 +13,7 @@ use std::{
|
||||
Arc, Mutex,
|
||||
},
|
||||
thread,
|
||||
time::SystemTime,
|
||||
time::{Instant, SystemTime},
|
||||
};
|
||||
|
||||
fn p(n: f64) -> f64 {
|
||||
@ -127,24 +127,32 @@ fn main() {
|
||||
scope.spawn(move || worker(workloads, i, progress, &arcclone, threads_done));
|
||||
}
|
||||
|
||||
loop {
|
||||
let n = progress.load(std::sync::atomic::Ordering::Relaxed);
|
||||
let threads_completed = threads_done.load(std::sync::atomic::Ordering::Relaxed);
|
||||
let mut last_progress = Instant::now();
|
||||
|
||||
println!(
|
||||
"Progress: {:0>width$}/{} ({:>3}%) | {:0>t_width$}",
|
||||
n,
|
||||
N,
|
||||
(n as f64 / NF * 100.0).min(100.0).floor(),
|
||||
threads_completed,
|
||||
width = N.to_string().len(),
|
||||
t_width = THREADS.to_string().len()
|
||||
);
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
loop {
|
||||
let threads_completed = threads_done.load(std::sync::atomic::Ordering::Relaxed);
|
||||
|
||||
if threads_completed == THREADS {
|
||||
break;
|
||||
}
|
||||
|
||||
if last_progress.elapsed().as_millis() >= 500 {
|
||||
last_progress = Instant::now();
|
||||
|
||||
let n = progress.load(std::sync::atomic::Ordering::Relaxed);
|
||||
|
||||
println!(
|
||||
"Progress: {:0>width$}/{} ({:>3}%) | {:0>t_width$}",
|
||||
n,
|
||||
N,
|
||||
(n as f64 / NF * 100.0).min(100.0).floor(),
|
||||
threads_completed,
|
||||
width = N.to_string().len(),
|
||||
t_width = THREADS.to_string().len()
|
||||
);
|
||||
}
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user