diff --git a/src/lib.rs b/src/lib.rs index 0281954..5b51db9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -208,6 +208,33 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq { (self.extended_gcd(other), self.lcm(other)) } + /// Inverse of the number modulo the modulus + /// + /// # Examples + /// + /// ~~~ + /// # extern crate num_integer; + /// # fn main() { + /// # use num_integer::Integer; + /// assert_eq!((10isize).invmod(&11isize).unwrap(), 10isize); + /// assert_eq!((173isize).invmod(&1729isize).unwrap(), 10isize); + /// # } + /// ~~~ + #[inline] + fn invmod(&self, modulus: &Self) -> Option + where + Self: Clone, + { + let ExtendedGcd { gcd, x, .. } = self.extended_gcd(modulus); + if !gcd.is_one() { + None + } else if x < Self::zero() { + Some(x + modulus.clone()) + } else { + Some(x) + } + } + /// Deprecated, use `is_multiple_of` instead. fn divides(&self, other: &Self) -> bool; @@ -1341,3 +1368,11 @@ fn test_multinomial() { check_multinomial!(u64, &[0], 1); check_multinomial!(u64, &[12345], 1); } + +#[test] +fn test_invmod() { + assert_eq!((10isize).invmod(&11isize).unwrap(), 10isize); + assert_eq!((173isize).invmod(&1729isize).unwrap(), 10isize); + + assert!((10isize).invmod(&12isize).is_none()); +}