Skip to main content

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}