Skip to main content

malachite_nz/integer/arithmetic/
gcd.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::integer::Integer;
10use crate::natural::Natural;
11use malachite_base::num::arithmetic::traits::{Gcd, GcdAssign};
12
13impl Gcd<Self> for Integer {
14    type Output = Natural;
15
16    /// Computes the GCD (greatest common divisor) of two [`Integer`]s, taking both by value.
17    ///
18    /// The GCD is always non-negative, so it is a [`Natural`]. The GCD of 0 and $n$, for any $n$,
19    /// is $|n|$; in particular, $\gcd(0, 0) = 0$.
20    ///
21    /// $$
22    /// f(x, y) = \gcd(|x|, |y|).
23    /// $$
24    ///
25    /// # Worst-case complexity
26    /// $T(n) = O(n (\log n)^2 \log\log n)$
27    ///
28    /// $M(n) = O(n \log n)$
29    ///
30    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
31    /// other.significant_bits())`.
32    ///
33    /// # Examples
34    /// ```
35    /// use malachite_base::num::arithmetic::traits::Gcd;
36    /// use malachite_base::num::basic::traits::Zero;
37    /// use malachite_nz::integer::Integer;
38    ///
39    /// assert_eq!(Integer::from(-12).gcd(Integer::from(90)), 6);
40    /// assert_eq!(Integer::from(3).gcd(Integer::from(-5)), 1);
41    /// assert_eq!(Integer::from(-7).gcd(Integer::ZERO), 7);
42    /// ```
43    #[inline]
44    fn gcd(self, other: Self) -> Natural {
45        self.abs.gcd(other.abs)
46    }
47}
48
49impl<'a> Gcd<&'a Self> for Integer {
50    type Output = Natural;
51
52    /// Computes the GCD (greatest common divisor) of two [`Integer`]s, taking the first by value
53    /// and the second by reference.
54    ///
55    /// The GCD is always non-negative, so it is a [`Natural`]. The GCD of 0 and $n$, for any $n$,
56    /// is $|n|$; in particular, $\gcd(0, 0) = 0$.
57    ///
58    /// $$
59    /// f(x, y) = \gcd(|x|, |y|).
60    /// $$
61    ///
62    /// # Worst-case complexity
63    /// $T(n) = O(n (\log n)^2 \log\log n)$
64    ///
65    /// $M(n) = O(n \log n)$
66    ///
67    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
68    /// other.significant_bits())`.
69    ///
70    /// # Examples
71    /// ```
72    /// use malachite_base::num::arithmetic::traits::Gcd;
73    /// use malachite_base::num::basic::traits::Zero;
74    /// use malachite_nz::integer::Integer;
75    ///
76    /// assert_eq!(Integer::from(-12).gcd(&Integer::from(90)), 6);
77    /// assert_eq!(Integer::from(3).gcd(&Integer::from(-5)), 1);
78    /// assert_eq!(Integer::from(-7).gcd(&Integer::ZERO), 7);
79    /// ```
80    #[inline]
81    fn gcd(self, other: &'a Self) -> Natural {
82        self.abs.gcd(&other.abs)
83    }
84}
85
86impl Gcd<Integer> for &Integer {
87    type Output = Natural;
88
89    /// Computes the GCD (greatest common divisor) of two [`Integer`]s, taking the first by
90    /// reference and the second by value.
91    ///
92    /// The GCD is always non-negative, so it is a [`Natural`]. The GCD of 0 and $n$, for any $n$,
93    /// is $|n|$; in particular, $\gcd(0, 0) = 0$.
94    ///
95    /// $$
96    /// f(x, y) = \gcd(|x|, |y|).
97    /// $$
98    ///
99    /// # Worst-case complexity
100    /// $T(n) = O(n (\log n)^2 \log\log n)$
101    ///
102    /// $M(n) = O(n \log n)$
103    ///
104    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
105    /// other.significant_bits())`.
106    ///
107    /// # Examples
108    /// ```
109    /// use malachite_base::num::arithmetic::traits::Gcd;
110    /// use malachite_base::num::basic::traits::Zero;
111    /// use malachite_nz::integer::Integer;
112    ///
113    /// assert_eq!((&Integer::from(-12)).gcd(Integer::from(90)), 6);
114    /// assert_eq!((&Integer::from(3)).gcd(Integer::from(-5)), 1);
115    /// assert_eq!((&Integer::from(-7)).gcd(Integer::ZERO), 7);
116    /// ```
117    #[inline]
118    fn gcd(self, other: Integer) -> Natural {
119        other.abs.gcd(&self.abs)
120    }
121}
122
123impl Gcd<&Integer> for &Integer {
124    type Output = Natural;
125
126    /// Computes the GCD (greatest common divisor) of two [`Integer`]s, taking both by reference.
127    ///
128    /// The GCD is always non-negative, so it is a [`Natural`]. The GCD of 0 and $n$, for any $n$,
129    /// is $|n|$; in particular, $\gcd(0, 0) = 0$.
130    ///
131    /// $$
132    /// f(x, y) = \gcd(|x|, |y|).
133    /// $$
134    ///
135    /// # Worst-case complexity
136    /// $T(n) = O(n (\log n)^2 \log\log n)$
137    ///
138    /// $M(n) = O(n \log n)$
139    ///
140    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
141    /// other.significant_bits())`.
142    ///
143    /// # Examples
144    /// ```
145    /// use malachite_base::num::arithmetic::traits::Gcd;
146    /// use malachite_base::num::basic::traits::Zero;
147    /// use malachite_nz::integer::Integer;
148    ///
149    /// assert_eq!((&Integer::from(-12)).gcd(&Integer::from(90)), 6);
150    /// assert_eq!((&Integer::from(3)).gcd(&Integer::from(-5)), 1);
151    /// assert_eq!((&Integer::from(-7)).gcd(&Integer::ZERO), 7);
152    /// ```
153    #[inline]
154    fn gcd(self, other: &Integer) -> Natural {
155        (&self.abs).gcd(&other.abs)
156    }
157}
158
159impl GcdAssign<Self> for Integer {
160    /// Replaces an [`Integer`] with the GCD (greatest common divisor) of it and another
161    /// [`Integer`], taking the [`Integer`] on the right-hand side by value.
162    ///
163    /// The GCD is always non-negative. The GCD of 0 and $n$, for any $n$, is $|n|$; in particular,
164    /// $\gcd(0, 0) = 0$.
165    ///
166    /// $$
167    /// x \gets \gcd(|x|, |y|).
168    /// $$
169    ///
170    /// # Worst-case complexity
171    /// $T(n) = O(n (\log n)^2 \log\log n)$
172    ///
173    /// $M(n) = O(n \log n)$
174    ///
175    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
176    /// other.significant_bits())`.
177    ///
178    /// # Examples
179    /// ```
180    /// use malachite_base::num::arithmetic::traits::GcdAssign;
181    /// use malachite_base::num::basic::traits::Zero;
182    /// use malachite_nz::integer::Integer;
183    ///
184    /// let mut x = Integer::from(-12);
185    /// x.gcd_assign(Integer::from(90));
186    /// assert_eq!(x, 6);
187    ///
188    /// let mut x = Integer::from(-7);
189    /// x.gcd_assign(Integer::ZERO);
190    /// assert_eq!(x, 7);
191    /// ```
192    #[inline]
193    fn gcd_assign(&mut self, other: Self) {
194        self.sign = true;
195        self.abs.gcd_assign(other.abs);
196    }
197}
198
199impl<'a> GcdAssign<&'a Self> for Integer {
200    /// Replaces an [`Integer`] with the GCD (greatest common divisor) of it and another
201    /// [`Integer`], taking the [`Integer`] on the right-hand side by reference.
202    ///
203    /// The GCD is always non-negative. The GCD of 0 and $n$, for any $n$, is $|n|$; in particular,
204    /// $\gcd(0, 0) = 0$.
205    ///
206    /// $$
207    /// x \gets \gcd(|x|, |y|).
208    /// $$
209    ///
210    /// # Worst-case complexity
211    /// $T(n) = O(n (\log n)^2 \log\log n)$
212    ///
213    /// $M(n) = O(n \log n)$
214    ///
215    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
216    /// other.significant_bits())`.
217    ///
218    /// # Examples
219    /// ```
220    /// use malachite_base::num::arithmetic::traits::GcdAssign;
221    /// use malachite_base::num::basic::traits::Zero;
222    /// use malachite_nz::integer::Integer;
223    ///
224    /// let mut x = Integer::from(-12);
225    /// x.gcd_assign(&Integer::from(90));
226    /// assert_eq!(x, 6);
227    ///
228    /// let mut x = Integer::from(-7);
229    /// x.gcd_assign(&Integer::ZERO);
230    /// assert_eq!(x, 7);
231    /// ```
232    #[inline]
233    fn gcd_assign(&mut self, other: &'a Self) {
234        self.sign = true;
235        self.abs.gcd_assign(&other.abs);
236    }
237}