1pub fn v32_to_v64(v32: &Vec<u32>) -> Vec<u64> {
2 #[cfg(test)] assert!(v32.len() > 0);
3
4 v32.iter().map(|n| *n as u64).collect()
5}
6
7pub fn v64_to_v32(mut v64: Vec<u64>) -> Vec<u32> {
8 #[cfg(test)] assert!(v64.len() > 0);
9
10 for i in 0..(v64.len() - 1) {
11
12 if v64[i] >= (1 << 32) {
13 v64[i + 1] += v64[i] >> 32;
14 v64[i] %= 1 << 32;
15 }
16
17 }
18
19 let v64_len = v64.len() - 1;
20
21 if v64[v64_len] >= (1 << 32) {
22 v64.push(v64[v64_len] >> 32);
23 v64[v64_len] %= 1 << 32;
24 }
25
26 #[cfg(test)] assert!(v64.iter().all(|n| *n < (1 << 32)));
27
28 v64.into_iter().map(|n| n as u32).collect()
29}
30
31pub fn remove_suffix_0(vec: &mut Vec<u32>) {
32
33 while vec.len() > 1 && vec[vec.len() - 1] == 0 {
34 vec.pop().unwrap();
35 }
36
37}
38
39pub fn gcd_i32(mut a: i32, mut b: i32) -> i32 {
40 a = a.abs();
41 b = b.abs();
42
43 while a != 0 {
44 let r = b % a;
45 b = a;
46 a = r;
47 }
48
49 b
50}
51
52#[cfg(test)]
53pub fn are_close(a: &crate::Ratio, b: &crate::Ratio, thres: f64) -> bool {
54
55 if b.is_zero() {
56 let thres_to_rat = match crate::Ratio::from_ieee754_f64(thres) {
57 Ok(n) => n,
58 _ => { return false; }
59 };
60 return a.abs().leq_rat(&thres_to_rat);
61 }
62
63 let diff = match a.div_rat(b).abs().to_ieee754_f64() {
64 Ok(n) => n,
65 _ => {
66 return false;
67 }
68 };
69
70 1.0 - thres <= diff && diff <= 1.0 + thres
71}
72
73#[cfg(test)]
74mod tests {
75 use super::gcd_i32;
76
77 #[test]
78 fn gcd_i32_test() {
79 let samples = vec![
80 (24, 17, 1),
81 (0, 0, 0),
82 (0, 8, 8),
83 (1728, 93, 3),
84 (1048576, 84, 4),
85 (3003, 343, 7)
86 ];
87
88 for (a, b, c) in samples.into_iter() {
89 assert_eq!(gcd_i32(a, b), c);
90 assert_eq!(gcd_i32(-a, b), c);
91 assert_eq!(gcd_i32(a, -b), c);
92 assert_eq!(gcd_i32(-a, -b), c);
93 }
94
95 }
96
97}