refactor code

This commit is contained in:
code002lover 2024-07-23 01:36:30 +02:00
parent f6200bc99a
commit 90069e9ab4
3 changed files with 72 additions and 39 deletions

View File

@ -2,6 +2,7 @@
name = "isprime" name = "isprime"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
default-run = "isprime"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # 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_possible_truncation = "allow"
cast_precision_loss = "allow" cast_precision_loss = "allow"
cast_sign_loss = "allow" cast_sign_loss = "allow"
missing_errors_doc = "allow" missing_errors_doc = "allow"
[[bin]]
name = "isprime"

View File

@ -7,49 +7,70 @@ pub mod prime_utils {
x.bits() - 1 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] #[must_use]
pub fn is_prime(number: &BigUint) -> bool { pub fn is_prime(number: &BigUint) -> bool {
const ZERO: BigUint = BigUint::ZERO; if &*ONE >= number {
static TWO: Lazy<BigUint> = Lazy::new(|| BigUint::from(2u8));
if &BigUint::one() >= number {
return false; return false;
} }
if &BigUint::from(4u8) > number { if &*FOUR > number {
return true; return true;
} }
if number % &*TWO == ZERO { if !number.bit(0) {
return false; return false;
} }
// number = 2^a - 1 // mersenne numbers = 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 let is_mersenne = {
if TWO.pow(a as u32) - BigUint::one() != *number { let num_p2 = {
let mut i = BigUint::one(); 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 { &num_p2 == number
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 is_mersenne {
} return mersenne_check(number, a);
if i >= sqrtnum {
return true;
}
}
} }
//check if it's a mersenne prime let sqrtnum = number.sqrt() + &*ONE; //fake ceil function
let mut last = BigUint::from(4u8);
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 = (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;
}
}
} }
} }

View File

@ -13,7 +13,7 @@ use std::{
Arc, Mutex, Arc, Mutex,
}, },
thread, thread,
time::SystemTime, time::{Instant, SystemTime},
}; };
fn p(n: f64) -> f64 { fn p(n: f64) -> f64 {
@ -127,24 +127,32 @@ fn main() {
scope.spawn(move || worker(workloads, i, progress, &arcclone, threads_done)); scope.spawn(move || worker(workloads, i, progress, &arcclone, threads_done));
} }
loop { let mut last_progress = Instant::now();
let n = progress.load(std::sync::atomic::Ordering::Relaxed);
let threads_completed = threads_done.load(std::sync::atomic::Ordering::Relaxed);
println!( loop {
"Progress: {:0>width$}/{} ({:>3}%) | {:0>t_width$}", let threads_completed = threads_done.load(std::sync::atomic::Ordering::Relaxed);
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));
if threads_completed == THREADS { if threads_completed == THREADS {
break; 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));
} }
}); });