1#![allow(dead_code)]
2
3pub type Digit = u32;
4pub type DoubleDigit = u64;
5pub const BYTES: usize = 4;
6pub const BITS: usize = BYTES * 8;
7
8pub fn from_bytes_le(bytes: &[u8]) -> Vec<Digit> {
9 bytes.chunks(BYTES).map(|c| {
10 c.iter().rev().fold(0, |a, &x| (a << 8) | x as Digit)
11 }).collect()
12}
13
14pub fn from_bytes_be(bytes: &[u8]) -> Vec<Digit> {
15 let mut bytes = bytes.to_vec();
16 bytes.reverse();
17 from_bytes_le(&bytes)
18}
19
20pub fn to_bytes_le(num: &[Digit]) -> Vec<u8> {
21 let mut bytes: Vec<_> = num.iter().map(|c| {
22 (0..BYTES).map(move |i| (c >> (i * 8)) as u8 & 0xff)
23 }).flatten().collect();
24 bytes.truncate(bytes.iter().rposition(|x| *x != 0).unwrap_or(0) + 1);
25 bytes
26}
27
28pub fn to_bytes_be(num: &[Digit]) -> Vec<u8> {
29 let mut bytes = to_bytes_le(num);
30 bytes.reverse();
31 bytes
32}
33
34pub fn add(num: &mut Vec<Digit>, x: DoubleDigit) {
35 let mut carry = x;
36 for d in num.iter_mut() {
37 carry += *d as DoubleDigit;
38 *d = carry as Digit;
39 carry >>= BITS;
40 if carry == 0 { break }
41 }
42 if carry != 0 { num.push(carry as Digit) }
43}
44
45pub fn mul(num: &mut Vec<Digit>, x: DoubleDigit) {
46 let mut carry = 0;
47 for d in num.iter_mut() {
48 carry += *d as DoubleDigit * x;
49 *d = carry as Digit;
50 carry >>= BITS;
51 }
52 if carry != 0 { num.push(carry as Digit) }
53}
54
55pub fn div_rem(num: &mut Vec<Digit>, x: DoubleDigit) -> Digit {
56 let mut rem = 0;
57 for d in num.iter_mut().rev() {
58 let a = *d as DoubleDigit | (rem << BITS);
59 *d = (a / x) as Digit;
60 rem = a % x;
61 }
62 num.truncate(num.iter().rposition(|x| *x != 0).unwrap_or(0) + 1);
63 rem as Digit
64}