isPrime/src/is_prime.rs
Mystikfluu 63de9be895 optimize a bit
... again ...
2023-03-03 19:23:15 +01:00

74 lines
1.8 KiB
Rust

pub mod prime_utils {
use num::{BigUint, One, Zero};
use crate::primality_test::primality_tests::is_probably_prime;
#[must_use] pub fn log_2(x: &BigUint) -> u64 {
x.bits() - 1
}
#[must_use] pub fn is_prime(number: &BigUint, g_primes: &Vec<BigUint>) -> bool {
if BigUint::from(1u8) == *number {
return false;
}
if BigUint::from(4u8) > *number {
return true;
}
if number.sqrt().pow(2) == *number {
return false;
}
let two = BigUint::from(2u8);
// number = 2^a - 1
// a = log2(number + 1)
let a = log_2(&(number+1u8));
if BigUint::from(2u8).pow(a as u32)-BigUint::one() != *number {
let mut i = BigUint::one();
let one = BigUint::one();
let zero = BigUint::zero();
let sqrtnum = number.sqrt()+&one; //fake ceil function
if let Some(max_value) = g_primes.iter().max() {
if max_value > &sqrtnum {
for prime in g_primes {
if prime<&sqrtnum && number%prime == zero {
return false;
}
}
}
}
if !is_probably_prime(number,5) {
return false;
}
loop {
i += &one;
if number%&i == zero {
return false;
}
if i == sqrtnum {
return true;
}
}
}
// 4 12 194
let mut last = BigUint::from(4u8);
for _i in 2..a {
last = (last.pow(2)-&two)%number;
}
last == BigUint::from(0u8)
}
}