Skip to main content

smart_big_rational/
primes.rs

1// Copyright 2026 The SmartBigRational Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15include!(concat!(env!("OUT_DIR"), "/primes.rs"));
16
17pub fn known_odd_prime_factor_indices(x: usize) -> Option<impl Iterator<Item = (u16, u16)>> {
18    ODD_FACTOR_INDICES
19        .get(x / 2)
20        .map(|array| array.iter().copied().filter(|(p, _)| *p != 0))
21}
22
23#[cfg(test)]
24mod test {
25    use super::*;
26    use crate::util::OddDivider;
27
28    #[test]
29    fn test_dividers_u16() {
30        for (i, &p) in ODD_PRIMES.iter().enumerate() {
31            let divider = OddDivider {
32                divisor: p,
33                multiplier: ODD_PRIME_DIVIDERS_U16[i],
34                shift: p.ilog2(),
35            };
36            for x in 0..=u16::MAX {
37                let (quo, rem) = divider.div_rem(x);
38                assert_eq!(x / p, quo);
39                assert_eq!(x % p, rem);
40            }
41        }
42    }
43
44    #[test]
45    fn test_dividers_u32() {
46        for (i, &p) in ODD_PRIMES.iter().enumerate() {
47            let p = p as u32;
48            let divider = OddDivider {
49                divisor: p,
50                multiplier: ODD_PRIME_DIVIDERS_U32[i],
51                shift: p.ilog2(),
52            };
53            for x in (0..=u16::MAX as u32)
54                .chain((0..=u16::MAX as u32).map(|x| u32::MAX - x))
55                .chain((0..32).map(|i| 1 << i))
56                .chain((0..32).map(|i| !(1 << i)))
57                .chain((0..32).map(|i| (1 << i) - 1))
58            {
59                let (quo, rem) = divider.div_rem(x);
60                assert_eq!(x / p, quo);
61                assert_eq!(x % p, rem);
62            }
63        }
64    }
65
66    #[test]
67    fn test_dividers_u64() {
68        for (i, &p) in ODD_PRIMES.iter().enumerate() {
69            let p = p as u64;
70            let divider = OddDivider {
71                divisor: p,
72                multiplier: ODD_PRIME_DIVIDERS_U64[i],
73                shift: p.ilog2(),
74            };
75            for x in (0..=u16::MAX as u64)
76                .chain((0..=u16::MAX as u64).map(|x| u64::MAX - x))
77                .chain((0..64).map(|i| 1 << i))
78                .chain((0..64).map(|i| !(1 << i)))
79                .chain((0..64).map(|i| (1 << i) - 1))
80            {
81                let (quo, rem) = divider.div_rem(x);
82                assert_eq!(x / p, quo);
83                assert_eq!(x % p, rem);
84            }
85        }
86    }
87}