large_primes/primality/standard.rs
1use num_bigint::BigUint;
2use num_traits::{ One, Zero };
3
4/// Performs the standard primality test by checking for prime factors from 2 to the square root of the given number.
5///
6/// This function checks whether the provided number is prime by testing for prime factors in the range from 2
7/// to the square root of the number (inclusive). It returns `true` if the number has no prime factors in that range,
8/// indicating that it is prime.
9///
10/// # Arguments
11///
12/// * `num` - A reference to a `BigUint` representing the number to test for primality.
13///
14/// # Returns
15///
16/// * `true` if `num` passes the standard primality test (has no prime factors from 2 to sqrt(num)).
17/// * `false` if `num` has a prime factor in the specified range or if `num` is less than or equal to 1.
18/// Note that the function returns `true` when `num` is 2, as it is the only even prime number.
19///
20/// # Examples
21///
22/// ```
23/// use num_bigint::BigUint;
24/// use large_primes::standard;
25///
26/// let prime_number = BigUint::from(19u32);
27/// assert!(standard(&prime_number));
28///
29/// let non_prime = BigUint::from(15u32);
30/// assert!(!standard(&non_prime));
31/// ```
32pub fn standard(num: &BigUint) -> bool {
33 // Standard test for prime factors from 2 to sqrt(num)+1
34 if *num <= BigUint::one() {
35 return false;
36 }
37 if *num == BigUint::from(2u32) {
38 return true;
39 }
40
41 let sqrt_num = num.sqrt() + BigUint::one();
42
43 let mut factor = BigUint::from(2u32);
44 while &factor <= &sqrt_num {
45 if num % &factor == BigUint::zero() {
46 return false;
47 }
48 factor += BigUint::one();
49 }
50
51 true
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn edge_cases() {
60 // Test case 0: False
61 assert_eq!(standard(&BigUint::zero()), false);
62
63 // Test case 1: False
64 assert_eq!(standard(&BigUint::one()), false);
65
66 // Test case 2: True
67 assert_eq!(standard(&BigUint::from(2u32)), true);
68
69 // Test case 3: True
70 assert_eq!(standard(&BigUint::from(3u32)), true);
71
72 // Test case 4: False
73 assert_eq!(standard(&BigUint::from(4u32)), false);
74 }
75
76 #[test]
77 fn large_primes() {
78 let primes = [
79 "871603259",
80 "98762051",
81 "1000000007",
82 "123575321",
83 "193818613",
84 "444444443",
85 "999999937",
86 "1000000000039",
87 "9999999929",
88 ];
89
90 for prime in primes {
91 let prime = BigUint::parse_bytes(prime.as_bytes(), 10).unwrap();
92 assert_eq!(standard(&prime), true);
93 }
94 }
95
96 #[test]
97 fn large_composites() {
98 let primes = ["914491", "15959", "767857", "14293", "680123", "617237"];
99
100 for i in 0..primes.len() {
101 for j in 0..primes.len() {
102 if i == j {
103 continue;
104 }
105 let composite =
106 BigUint::parse_bytes(primes[i].as_bytes(), 10).unwrap() *
107 BigUint::parse_bytes(primes[j].as_bytes(), 10).unwrap();
108 assert_eq!(standard(&composite), false);
109 }
110 }
111 }
112}