algorithms_edu/algo/math/
gcd.rs1use num_traits::{PrimInt, Signed, Unsigned};
2
3pub trait Gcd: PrimInt + Signed {
4 fn gcd(self, other: Self) -> Self {
5 if other == Self::zero() {
6 self.abs()
7 } else {
8 other.gcd(self % other)
9 }
10 }
11}
12
13pub trait GcdUnsigned: PrimInt + Unsigned {
14 fn gcd(self, other: Self) -> Self {
15 if other == Self::zero() {
16 self
17 } else {
18 other.gcd(self % other)
19 }
20 }
21}
22
23impl<I: Signed + PrimInt> Gcd for I {}
24
25impl<I: Unsigned + PrimInt> GcdUnsigned for I {}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30 #[test]
31 fn test_gcd() {
32 assert_eq!(12i32.gcd(18), 6);
33 assert_eq!((-12i32).gcd(18), 6);
34 assert_eq!(12i32.gcd(-18), 6);
35 assert_eq!((-12i32).gcd(-18), 6);
36 assert_eq!((5i32).gcd(0), 5);
37 assert_eq!((0i32).gcd(5), 5);
38 assert_eq!((-5i32).gcd(0), 5);
39 assert_eq!((0i32).gcd(-5), 5);
40 assert_eq!((0i32).gcd(0), 0);
41
42 assert_eq!(12u32.gcd(18), 6);
43 assert_eq!(12u128.gcd(18), 6);
44 assert_eq!(12i128.gcd(18), 6);
45 }
46}