1pub use std::{
56 ops::{
57 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
58 DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
59 SubAssign,
60 },
61 str::FromStr,
62};
63
64pub use serde::{Deserialize, Serialize};
65
66#[macro_use]
67pub mod macros;
68
69pub fn mul8(x: u8, y: u8) -> (u8, u8) {
70 let z = x as u16 * y as u16;
71 ((z >> 8) as u8, z as u8)
72}
73
74pub fn mul_r(z: u8, x: u8, y: u8) -> (u8, u8) {
75 let (hi, lo) = mul8(x, y);
76 let (lo, c) = lo.overflowing_add(z);
77 let (hi, _) = hi.overflowing_add(c as u8);
78 (hi, lo)
79}
80
81pub fn mul_carry(z: u8, x: u8, y: u8, carry: u8) -> (u8, u8) {
82 let (hi, lo) = mul8(x, y);
83 let (lo, c) = lo.overflowing_add(carry);
84 let (hi, _) = hi.overflowing_add(c as u8);
85 let (lo, c) = lo.overflowing_add(z);
86 let (hi, _) = hi.overflowing_add(c as u8);
87 (hi, lo)
88}
89
90pub fn div8(hi: u8, lo: u8, y: u8) -> (u8, u8) {
92 if y != 0 && y <= hi {
93 panic!("forbidden");
94 }
95
96 let z = (hi as u16) << 8 | lo as u16;
97 ((z / y as u16) as u8, (z % y as u16) as u8)
98}
99
100pub fn reciprocal_2by1(d: u8) -> u8 {
102 let (reciprocal, _) = div8(!d, !0u8, d);
103 reciprocal
104}
105
106pub fn div_rem_2by1(uh: u8, ul: u8, d: u8, reciprocal: u8) -> (u8, u8) {
110 let (qh, ql) = mul8(reciprocal, uh);
111 let (ql, carry) = ql.overflowing_add(ul);
112 let (mut qh, _) = qh.overflowing_add(uh);
113 qh = qh.overflowing_add(carry as u8 + 1).0;
114
115 let (mut r, _) = ul.overflowing_sub((qh as u16 * d as u16) as u8);
116
117 if r > ql {
118 qh = qh.overflowing_sub(1).0;
119 r = r.overflowing_add(d).0;
120 }
121
122 if r >= d {
123 qh = qh.overflowing_add(1).0;
124 r = r.overflowing_sub(d).0;
125 }
126
127 (qh, r)
128}
129
130pub fn sub_mul(nx: &[u8], y: &[u8], multiplier: u8) -> (Vec<u8>, u8) {
133 let mut x = vec![0u8; nx.len()];
134 x.copy_from_slice(nx);
135 let mut borrow = 0u8;
136
137 for i in 0..y.len() {
138 let (s, carry1) = x[i].overflowing_sub(borrow);
139 let (ph, pl) = mul8(y[i], multiplier);
140 let (t, carry2) = s.overflowing_sub(pl);
141 x[i] = t;
142 borrow = ph + carry1 as u8 + carry2 as u8;
143 }
144
145 (x, borrow)
146}
147
148pub fn add_slice(x: &[u8], y: &[u8]) -> (Vec<u8>, u8) {
151 let mut x = vec![0u8; x.len()];
152 let mut carry = false;
153 for i in 0..y.len() {
154 (x[i], carry) = x[i].overflowing_add(y[i] + carry as u8);
155 }
156 (x, carry as u8)
157}
158
159define!(
160 U24,
161 3,
162 "24-bit unsigned integer represented as little-endian byte order."
163);
164
165define!(
166 U40,
167 5,
168 "40-bit unsigned integer represented as little-endian byte order."
169);
170
171define!(
172 U48,
173 6,
174 "48-bit unsigned integer represented as little-endian byte order."
175);
176
177define!(
178 U56,
179 7,
180 "56-bit unsigned integer represented as little-endian byte order."
181);
182
183define!(
184 U72,
185 9,
186 "72-bit unsigned integer represented as little-endian byte order."
187);
188
189define!(
190 U80,
191 10,
192 "80-bit unsigned integer represented as little-endian byte order."
193);
194
195define!(
196 U88,
197 11,
198 "88-bit unsigned integer represented as little-endian byte order."
199);
200
201define!(
202 U96,
203 12,
204 "96-bit unsigned integer represented as little-endian byte order."
205);
206
207define!(
208 U104,
209 13,
210 "104-bit unsigned integer represented as little-endian byte order."
211);
212
213define!(
214 U112,
215 14,
216 "112-bit unsigned integer represented as little-endian byte order."
217);
218
219define!(
220 U120,
221 15,
222 "120-bit unsigned integer represented as little-endian byte order."
223);
224
225define!(
226 U136,
227 17,
228 "136-bit unsigned integer represented as little-endian byte order."
229);
230
231define!(
232 U144,
233 18,
234 "144-bit unsigned integer represented as little-endian byte order."
235);
236
237define!(
238 U152,
239 19,
240 "152-bit unsigned integer represented as little-endian byte order."
241);
242
243define!(
244 U160,
245 20,
246 "160-bit unsigned integer represented as little-endian byte order."
247);
248
249define!(
250 U168,
251 21,
252 "168-bit unsigned integer represented as little-endian byte order."
253);
254
255define!(
256 U176,
257 22,
258 "176-bit unsigned integer represented as little-endian byte order."
259);
260
261define!(
262 U184,
263 23,
264 "184-bit unsigned integer represented as little-endian byte order."
265);
266
267define!(
268 U192,
269 24,
270 "192-bit unsigned integer represented as little-endian byte order."
271);
272
273define!(
274 U200,
275 25,
276 "200-bit unsigned integer represented as little-endian byte order."
277);
278
279define!(
280 U208,
281 26,
282 "208-bit unsigned integer represented as little-endian byte order."
283);
284
285define!(
286 U216,
287 27,
288 "216-bit unsigned integer represented as little-endian byte order."
289);
290
291define!(
292 U224,
293 28,
294 "224-bit unsigned integer represented as little-endian byte order."
295);
296
297define!(
298 U232,
299 29,
300 "232-bit unsigned integer represented as little-endian byte order."
301);
302
303define!(
304 U240,
305 30,
306 "240-bit unsigned integer represented as little-endian byte order."
307);
308
309define!(
310 U248,
311 31,
312 "248-bit unsigned integer represented as little-endian byte order."
313);
314
315define!(
316 U256,
317 32,
318 "256-bit unsigned integer represented as little-endian byte order."
319);
320
321#[cfg(test)]
322mod test_un_prim {
323 use super::*;
324
325 #[test]
326 fn test_macro() {
327 define!(
328 U8,
329 1,
330 "8-bit unsigned integer represented as little-endian byte order."
331 );
332
333 let x: U8 = 200u8.into();
334 assert_eq!(200u8, x.into());
335 }
336}