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"
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"

View File

@ -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;
}
}
}
}

View File

@ -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));
}
});