Skip to main content

c_prime/
func.rs

1use machine_prime::PRIME_TABLE;
2
3/// More efficient primality for compile-time evaluation
4const fn small_prime(x: u64) -> bool{
5   if x==2{
6      return true;
7   }
8   if x&1==0{
9     return false;
10   }
11   let mut idx=0usize;
12   
13   while idx<256{
14     let prod = PRIME_TABLE[idx].wrapping_mul(x);
15     if prod <= PRIME_TABLE[idx+1]{
16        return prod==1
17     }
18     idx+=2;
19   }
20   return true;
21}
22
23const fn bounded_search(mut x: u128, stride: u128) -> u128{
24    loop{
25     x= x.wrapping_add(stride);
26     
27     if x == 0 || x == u128::MAX{
28       panic!("Exceeded bounds");
29     }
30     
31     if x < 537289{
32      let n = x as u64;
33       if small_prime(n){
34          return x;     
35       }
36     }
37     else{
38     if machine_prime::is_prime_128(x){
39        return x;
40     }
41    } 
42   }
43}
44/// slightly faster to eek out performance in compile-time evaluation
45const fn bounded_search_64(mut x: u64, stride: u64) -> u64{
46loop{
47     x= x.wrapping_add(stride);
48     
49     if x == 0 || x == u64::MAX{
50       panic!("Exceeded bounds");
51     }
52     
53     if x < 537289{
54       if small_prime(x){
55          return x;     
56       }
57     }
58     else{
59     if machine_prime::is_prime(x){
60        return x;
61     }
62    } 
63   }
64}
65
66const fn next_prime_64(x: u64) -> u64{
67     bounded_search_64(x,1)
68}
69/// Returns the next prime
70pub const fn next_prime(x: u128) -> u128{
71    bounded_search(x,1)
72}
73
74/// Returns the previous prime
75pub const fn prev_prime(x: u128) -> u128{
76   bounded_search(x,u128::MAX)
77}
78
79/// Initialises an  array of sequential 128-bit primes
80///
81/// An array is initialised with the primes sequentially from START. This can be calculated at compile time
82pub const fn prime_array<const S: usize>(mut start: u128) -> [u128;S]{
83    let mut counter = 0usize;
84    let mut valarray : [u128;S] = [0u128;S];
85    loop{
86        start=next_prime(start);
87        valarray[counter]=start;
88        counter+=1;    
89        if counter == S{
90          return valarray;
91        }
92      }
93}
94
95
96/// Initialises an  array of sequential 64-bit primes
97pub const fn prime_array_64<const S: usize>(mut start: u64) -> [u64;S]{
98    let mut counter = 0usize;
99    let mut valarray : [u64;S] = [0u64;S];
100    loop{
101        let interim = next_prime_64(start);
102        start= interim;
103        valarray[counter]=start;
104        counter+=1;    
105        if counter == S{
106          return valarray;
107        }
108      }
109}
110
111/// Initialises an  array of sequential 32-bit primes
112pub const fn prime_array_32<const S: usize>(mut start: u32) -> [u32;S]{
113    let mut counter = 0usize;
114    let mut valarray : [u32;S] = [0u32;S];
115    loop{
116         let interim = next_prime_64(start as u64);
117        if interim >= 1u64<<32{
118           panic!("Exceeded the datatype max");
119        }
120        start=interim as u32;
121        valarray[counter]=start;
122        counter+=1;    
123        if counter == S{
124          return valarray;
125        }
126      }
127}
128
129/// Initialises an  array of sequential 16-bit primes
130pub const fn prime_array_16<const S: usize>(mut start: u16) -> [u16;S]{
131    let mut counter = 0usize;
132    let mut valarray : [u16;S] = [0u16;S];
133    loop{
134        
135         let interim = next_prime_64(start as u64);
136        if interim >= 1u64<<16{
137           panic!("Exceeded the datatype max");
138        }
139        start=interim as u16;
140        valarray[counter]=start;
141        counter+=1;    
142        if counter == S{
143          return valarray;
144        }
145      }
146}
147
148/// Initialises an array of sequantial multiplicative inverses of primes over Z/2^64
149pub const fn prime_inv_array_64<const S: usize>(mut start: u64) -> [u64;S]{
150    let mut counter = 0usize;
151    if start < 2{
152       panic!("2 has no inverse over 2^64");
153    }
154    let mut valarray : [u64;S] = [0u64;S];
155    loop{
156        start=next_prime_64(start);
157        valarray[counter]=machine_prime::mul_inv2(start);
158        counter+=1;    
159        if counter == S{
160          return valarray;
161        }
162      }
163}
164
165/// Initialises an  array of sequential multiplicative inverses of primes over Z/2^128
166pub const fn prime_inv_array<const S: usize>(mut start: u128) -> [u128;S]{
167    let mut counter = 0usize;
168    if start < 2{
169       panic!("2 has no multiplicative inverse over 2^128");
170    }
171    let mut valarray : [u128;S] = [0u128;S];
172    loop{
173        start=next_prime(start);
174        valarray[counter]=machine_prime::mul_inv2_128(start);
175        counter+=1;    
176        if counter == S{
177          return valarray;
178        }
179      }
180}