malachite_nz/natural/arithmetic/abs_diff.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5// Copyright © 1991-2018, 2020 Free Software Foundation, Inc.
6//
7// This file is part of Malachite.
8//
9// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
10// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
11// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
12
13use crate::natural::Natural;
14use malachite_base::num::arithmetic::traits::{AbsDiff, AbsDiffAssign};
15
16impl AbsDiff<Self> for Natural {
17 type Output = Self;
18
19 /// Computes the absolute value of the difference between two [`Natural`]s, taking both by
20 /// value.
21 ///
22 /// $$
23 /// f(x, y) = |x - y|.
24 /// $$
25 ///
26 /// # Worst-case complexity
27 /// $T(n) = O(n)$
28 ///
29 /// $M(n) = O(1)$
30 ///
31 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
32 ///
33 /// # Examples
34 /// ```
35 /// use malachite_base::num::arithmetic::traits::{AbsDiff, Pow};
36 /// use malachite_base::num::basic::traits::Zero;
37 /// use malachite_nz::natural::Natural;
38 ///
39 /// assert_eq!(Natural::from(123u32).abs_diff(Natural::ZERO), 123);
40 /// assert_eq!(Natural::ZERO.abs_diff(Natural::from(123u32)), 123);
41 /// assert_eq!(Natural::from(456u32).abs_diff(Natural::from(123u32)), 333);
42 /// assert_eq!(Natural::from(123u32).abs_diff(Natural::from(456u32)), 333);
43 /// assert_eq!(
44 /// (Natural::from(10u32).pow(12) * Natural::from(3u32))
45 /// .abs_diff(Natural::from(10u32).pow(12)),
46 /// 2000000000000u64
47 /// );
48 /// assert_eq!(
49 /// Natural::from(10u32)
50 /// .pow(12)
51 /// .abs_diff(Natural::from(10u32).pow(12) * Natural::from(3u32)),
52 /// 2000000000000u64
53 /// );
54 /// ```
55 fn abs_diff(self, other: Self) -> Self {
56 if self >= other {
57 self - other
58 } else {
59 other - self
60 }
61 }
62}
63
64impl<'a> AbsDiff<&'a Self> for Natural {
65 type Output = Self;
66
67 /// Computes the absolute value of the difference between two [`Natural`]s, taking the first by
68 /// value and the second by reference.
69 ///
70 /// $$
71 /// f(x, y) = |x - y|.
72 /// $$
73 ///
74 /// # Worst-case complexity
75 /// $T(n) = O(n)$
76 ///
77 /// $M(n) = O(1)$
78 ///
79 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
80 /// other.significant_bits())`.
81 ///
82 /// # Examples
83 /// ```
84 /// use malachite_base::num::arithmetic::traits::{AbsDiff, Pow};
85 /// use malachite_base::num::basic::traits::Zero;
86 /// use malachite_nz::natural::Natural;
87 ///
88 /// assert_eq!(Natural::from(123u32).abs_diff(&Natural::ZERO), 123);
89 /// assert_eq!(Natural::ZERO.abs_diff(&Natural::from(123u32)), 123);
90 /// assert_eq!(Natural::from(456u32).abs_diff(&Natural::from(123u32)), 333);
91 /// assert_eq!(Natural::from(123u32).abs_diff(&Natural::from(456u32)), 333);
92 /// assert_eq!(
93 /// (Natural::from(10u32).pow(12) * Natural::from(3u32))
94 /// .abs_diff(&Natural::from(10u32).pow(12)),
95 /// 2000000000000u64
96 /// );
97 /// assert_eq!(
98 /// Natural::from(10u32)
99 /// .pow(12)
100 /// .abs_diff(&(Natural::from(10u32).pow(12) * Natural::from(3u32))),
101 /// 2000000000000u64
102 /// );
103 /// ```
104 fn abs_diff(self, other: &'a Self) -> Self {
105 if self >= *other {
106 self - other
107 } else {
108 other - self
109 }
110 }
111}
112
113impl AbsDiff<Natural> for &Natural {
114 type Output = Natural;
115
116 /// Computes the absolute value of the difference between two [`Natural`]s, taking the first by
117 /// reference and the second by value.
118 ///
119 /// $$
120 /// f(x, y) = |x - y|.
121 /// $$
122 ///
123 /// # Worst-case complexity
124 /// $T(n) = O(n)$
125 ///
126 /// $M(n) = O(n)$
127 ///
128 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
129 /// other.significant_bits())`.
130 ///
131 /// # Examples
132 /// ```
133 /// use malachite_base::num::arithmetic::traits::{AbsDiff, Pow};
134 /// use malachite_base::num::basic::traits::Zero;
135 /// use malachite_nz::natural::Natural;
136 ///
137 /// assert_eq!((&Natural::from(123u32)).abs_diff(Natural::ZERO), 123);
138 /// assert_eq!((&Natural::ZERO).abs_diff(Natural::from(123u32)), 123);
139 /// assert_eq!(
140 /// (&Natural::from(456u32)).abs_diff(Natural::from(123u32)),
141 /// 333
142 /// );
143 /// assert_eq!(
144 /// (&Natural::from(123u32)).abs_diff(Natural::from(456u32)),
145 /// 333
146 /// );
147 /// assert_eq!(
148 /// (&(Natural::from(10u32).pow(12) * Natural::from(3u32)))
149 /// .abs_diff(Natural::from(10u32).pow(12)),
150 /// 2000000000000u64
151 /// );
152 /// assert_eq!(
153 /// (&Natural::from(10u32).pow(12))
154 /// .abs_diff(Natural::from(10u32).pow(12) * Natural::from(3u32)),
155 /// 2000000000000u64
156 /// );
157 /// ```
158 fn abs_diff(self, other: Natural) -> Natural {
159 if *self >= other {
160 self - other
161 } else {
162 other - self
163 }
164 }
165}
166
167impl AbsDiff<&Natural> for &Natural {
168 type Output = Natural;
169
170 /// Computes the absolute value of the difference between two [`Natural`]s, taking both by
171 /// reference.
172 ///
173 /// $$
174 /// f(x, y) = |x - y|.
175 /// $$
176 ///
177 /// # Worst-case complexity
178 /// $T(n) = O(n)$
179 ///
180 /// $M(n) = O(n)$
181 ///
182 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
183 /// other.significant_bits())`.
184 ///
185 /// # Examples
186 /// ```
187 /// use malachite_base::num::arithmetic::traits::{AbsDiff, Pow};
188 /// use malachite_base::num::basic::traits::Zero;
189 /// use malachite_nz::natural::Natural;
190 ///
191 /// assert_eq!((&Natural::from(123u32)).abs_diff(&Natural::ZERO), 123);
192 /// assert_eq!((&Natural::ZERO).abs_diff(&Natural::from(123u32)), 123);
193 /// assert_eq!(
194 /// (&Natural::from(456u32)).abs_diff(&Natural::from(123u32)),
195 /// 333
196 /// );
197 /// assert_eq!(
198 /// (&Natural::from(123u32)).abs_diff(&Natural::from(456u32)),
199 /// 333
200 /// );
201 /// assert_eq!(
202 /// (&(Natural::from(10u32).pow(12) * Natural::from(3u32)))
203 /// .abs_diff(&Natural::from(10u32).pow(12)),
204 /// 2000000000000u64
205 /// );
206 /// assert_eq!(
207 /// (&Natural::from(10u32).pow(12))
208 /// .abs_diff(&(Natural::from(10u32).pow(12) * Natural::from(3u32))),
209 /// 2000000000000u64
210 /// );
211 /// ```
212 fn abs_diff(self, other: &Natural) -> Natural {
213 if self >= other {
214 self - other
215 } else {
216 other - self
217 }
218 }
219}
220
221impl AbsDiffAssign<Self> for Natural {
222 /// Subtracts a [`Natural`] by another [`Natural`] in place and takes the absolute value, taking
223 /// the [`Natural`] on the right-hand side by value.
224 ///
225 /// $$
226 /// x \gets |x - y|.
227 /// $$
228 ///
229 /// # Worst-case complexity
230 /// $T(n) = O(n)$
231 ///
232 /// $M(n) = O(1)$
233 ///
234 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
235 /// other.significant_bits())`.
236 ///
237 /// # Panics
238 /// Panics if `other` is greater than `self`.
239 ///
240 /// # Examples
241 /// ```
242 /// use malachite_base::num::arithmetic::traits::{AbsDiffAssign, Pow};
243 /// use malachite_base::num::basic::traits::Zero;
244 /// use malachite_nz::natural::Natural;
245 ///
246 /// let mut x = Natural::from(123u32);
247 /// x.abs_diff_assign(Natural::ZERO);
248 /// assert_eq!(x, 123);
249 ///
250 /// let mut x = Natural::ZERO;
251 /// x.abs_diff_assign(Natural::from(123u32));
252 /// assert_eq!(x, 123);
253 ///
254 /// let mut x = Natural::from(456u32);
255 /// x.abs_diff_assign(Natural::from(123u32));
256 /// assert_eq!(x, 333);
257 ///
258 /// let mut x = Natural::from(123u32);
259 /// x.abs_diff_assign(Natural::from(456u32));
260 /// assert_eq!(x, 333);
261 ///
262 /// let mut x = Natural::from(10u32).pow(12) * Natural::from(3u32);
263 /// x.abs_diff_assign(Natural::from(10u32).pow(12));
264 /// assert_eq!(x, 2000000000000u64);
265 ///
266 /// let mut x = Natural::from(10u32).pow(12);
267 /// x.abs_diff_assign(Natural::from(10u32).pow(12) * Natural::from(3u32));
268 /// assert_eq!(x, 2000000000000u64);
269 /// ```
270 fn abs_diff_assign(&mut self, other: Self) {
271 if *self >= other {
272 *self -= other;
273 } else {
274 self.sub_right_assign_no_panic(&other);
275 }
276 }
277}
278
279impl<'a> AbsDiffAssign<&'a Self> for Natural {
280 /// Subtracts a [`Natural`] by another [`Natural`] in place and takes the absolute value, taking
281 /// the [`Natural`] on the right-hand side by reference.
282 ///
283 /// $$
284 /// x \gets |x - y|.
285 /// $$
286 ///
287 /// # Worst-case complexity
288 /// $T(n) = O(n)$
289 ///
290 /// $M(n) = O(1)$
291 ///
292 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
293 /// other.significant_bits())`.
294 ///
295 /// # Panics
296 /// Panics if `other` is greater than `self`.
297 ///
298 /// # Examples
299 /// ```
300 /// use malachite_base::num::arithmetic::traits::{AbsDiffAssign, Pow};
301 /// use malachite_base::num::basic::traits::Zero;
302 /// use malachite_nz::natural::Natural;
303 ///
304 /// let mut x = Natural::from(123u32);
305 /// x.abs_diff_assign(&Natural::ZERO);
306 /// assert_eq!(x, 123);
307 ///
308 /// let mut x = Natural::ZERO;
309 /// x.abs_diff_assign(&Natural::from(123u32));
310 /// assert_eq!(x, 123);
311 ///
312 /// let mut x = Natural::from(456u32);
313 /// x.abs_diff_assign(&Natural::from(123u32));
314 /// assert_eq!(x, 333);
315 ///
316 /// let mut x = Natural::from(123u32);
317 /// x.abs_diff_assign(&Natural::from(456u32));
318 /// assert_eq!(x, 333);
319 ///
320 /// let mut x = Natural::from(10u32).pow(12) * Natural::from(3u32);
321 /// x.abs_diff_assign(&Natural::from(10u32).pow(12));
322 /// assert_eq!(x, 2000000000000u64);
323 ///
324 /// let mut x = Natural::from(10u32).pow(12);
325 /// x.abs_diff_assign(&Natural::from(10u32).pow(12) * Natural::from(3u32));
326 /// assert_eq!(x, 2000000000000u64);
327 /// ```
328 fn abs_diff_assign(&mut self, other: &'a Self) {
329 if *self >= *other {
330 *self -= other;
331 } else {
332 self.sub_right_assign_no_panic(other);
333 }
334 }
335}