num_modular/
word.rs
1macro_rules! simple_word_impl {
2 ($S:ty, $D:ident) => {
3 pub type Word = $S;
4 pub type DoubleWord = $D;
5 pub use super::$D as DoubleWordModule;
6
7 #[inline(always)]
8 pub const fn ones(n: u32) -> Word {
9 if n == 0 {
10 0
11 } else {
12 Word::MAX >> (Word::BITS - n)
13 }
14 }
15
16 #[inline(always)]
17 pub const fn extend(word: Word) -> DoubleWord {
18 word as DoubleWord
19 }
20
21 #[inline(always)]
22 pub const fn low(dw: DoubleWord) -> Word {
23 dw as Word
24 }
25
26 #[inline(always)]
27 pub const fn high(dw: DoubleWord) -> Word {
28 (dw >> Word::BITS) as Word
29 }
30
31 #[inline(always)]
32 pub const fn split(dw: DoubleWord) -> (Word, Word) {
33 (low(dw), high(dw))
34 }
35
36 #[inline(always)]
37 pub const fn merge(low: Word, high: Word) -> DoubleWord {
38 extend(low) | extend(high) << Word::BITS
39 }
40
41 #[inline(always)]
43 pub const fn wmul(a: Word, b: Word) -> DoubleWord {
44 extend(a) * extend(b)
45 }
46
47 #[inline(always)]
49 pub const fn wsqr(a: Word) -> DoubleWord {
50 extend(a) * extend(a)
51 }
52
53 pub const fn nrem(n: DoubleWord, d: Word) -> Word {
55 (n % d as DoubleWord) as _
56 }
57 };
58}
59use simple_word_impl;
60
61pub mod u8 {
62 super::simple_word_impl!(u8, u16);
63}
64
65pub mod u16 {
66 super::simple_word_impl!(u16, u32);
67}
68
69pub mod u32 {
70 super::simple_word_impl!(u32, u64);
71}
72
73pub mod u64 {
74 super::simple_word_impl!(u64, u128);
75}
76
77pub mod usize {
78 #[cfg(target_pointer_width = "16")]
79 super::simple_word_impl!(usize, u32);
80 #[cfg(target_pointer_width = "32")]
81 super::simple_word_impl!(usize, u64);
82 #[cfg(target_pointer_width = "64")]
83 super::simple_word_impl!(usize, u128);
84}
85
86pub mod u128 {
87 use crate::double::udouble;
88 pub type Word = u128;
89 pub type DoubleWord = udouble;
90
91 #[inline]
92 pub const fn extend(word: Word) -> DoubleWord {
93 udouble { lo: word, hi: 0 }
94 }
95
96 #[inline(always)]
97 pub const fn low(dw: DoubleWord) -> Word {
98 dw.lo
99 }
100
101 #[inline(always)]
102 pub const fn high(dw: DoubleWord) -> Word {
103 dw.hi
104 }
105
106 #[inline]
107 pub const fn split(dw: DoubleWord) -> (Word, Word) {
108 (dw.lo, dw.hi)
109 }
110
111 #[inline]
112 pub const fn merge(low: Word, high: Word) -> DoubleWord {
113 udouble { lo: low, hi: high }
114 }
115
116 #[inline]
117 pub const fn wmul(a: Word, b: Word) -> DoubleWord {
118 udouble::widening_mul(a, b)
119 }
120
121 #[inline]
122 pub const fn wsqr(a: Word) -> DoubleWord {
123 udouble::widening_square(a)
124 }
125
126 #[inline]
127 pub fn nrem(n: DoubleWord, d: Word) -> Word {
128 n % d
129 }
130}