qfall_math/integer/z/
lcm.rs1use super::Z;
12use crate::traits::Lcm;
13use flint_sys::fmpz::fmpz_lcm;
14
15impl<Integer: Into<Z>> Lcm<Integer> for Z {
16 type Output = Z;
17
18 fn lcm(&self, other: Integer) -> Self::Output {
40 let other = other.into();
41 let mut out = Z::ZERO;
42 unsafe { fmpz_lcm(&mut out.value, &self.value, &other.value) };
43 out
44 }
45}
46
47#[cfg(test)]
48mod test_lcm {
49 use super::{Lcm, Z};
50
51 #[test]
54 fn small() {
55 let pos_1 = Z::from(10);
56 let pos_2 = Z::from(15);
57 let neg_1 = Z::from(-10);
58 let neg_2 = Z::from(-15);
59
60 let lcm_pos_1 = pos_1.lcm(&pos_2);
61 let lcm_pos_2 = pos_2.lcm(&pos_1);
62 let lcm_pos_eq = pos_1.lcm(&pos_1);
63 let lcm_mix_1 = pos_1.lcm(&neg_1);
64 let lcm_mix_2 = neg_2.lcm(&pos_1);
65 let lcm_neg_1 = neg_1.lcm(&neg_2);
66 let lcm_neg_2 = neg_2.lcm(&neg_1);
67 let lcm_neg_eq = neg_2.lcm(&neg_2);
68
69 assert_eq!(Z::from(30), lcm_pos_1);
70 assert_eq!(Z::from(30), lcm_pos_2);
71 assert_eq!(Z::from(10), lcm_pos_eq);
72 assert_eq!(Z::from(10), lcm_mix_1);
73 assert_eq!(Z::from(30), lcm_mix_2);
74 assert_eq!(Z::from(30), lcm_neg_1);
75 assert_eq!(Z::from(30), lcm_neg_2);
76 assert_eq!(Z::from(15), lcm_neg_eq);
77 }
78
79 #[test]
83 fn large() {
84 let pos = Z::from(i64::MAX);
85 let zero = Z::ZERO;
86 let neg = Z::from(i64::MIN);
87 let abs_neg = Z::MINUS_ONE * &neg;
88
89 let lcm_1 = pos.lcm(&zero);
90 let lcm_2 = pos.lcm(&pos);
91 let lcm_3 = neg.lcm(&zero);
92 let lcm_4 = neg.lcm(&neg);
93 let lcm_5 = pos.lcm(&neg);
94
95 assert_eq!(zero, lcm_1);
96 assert_eq!(pos, lcm_2);
97 assert_eq!(zero, lcm_3);
98 assert_eq!(abs_neg, lcm_4);
99 assert_eq!(pos * abs_neg, lcm_5);
100 }
101
102 #[test]
104 fn availability() {
105 let z = Z::ONE;
106
107 let _ = z.lcm(z.clone());
108 let _ = z.lcm(4_u8);
109 let _ = z.lcm(4_u16);
110 let _ = z.lcm(4_u32);
111 let _ = z.lcm(4_u64);
112 let _ = z.lcm(4_i8);
113 let _ = z.lcm(4_i16);
114 let _ = z.lcm(4_i32);
115 let _ = z.lcm(4_i64);
116 }
117}