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}