refactor code
This commit is contained in:
parent
f6200bc99a
commit
90069e9ab4
@ -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
|
||||||
|
|
||||||
@ -43,3 +44,6 @@ 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"
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
src/main.rs
36
src/main.rs
@ -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));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user