Skip to main content

malachite_nz/natural/arithmetic/
saturating_sub.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::natural::Natural;
10use malachite_base::num::arithmetic::traits::{CheckedSub, SaturatingSub, SaturatingSubAssign};
11use malachite_base::num::basic::traits::Zero;
12
13impl SaturatingSub<Self> for Natural {
14    type Output = Self;
15
16    /// Subtracts a [`Natural`] by another [`Natural`], taking both by value and returning 0 if the
17    /// result is negative.
18    ///
19    /// $$
20    /// f(x, y) = \max(x - y, 0).
21    /// $$
22    ///
23    /// # Worst-case complexity
24    /// $T(n) = O(n)$
25    ///
26    /// $M(n) = O(1)$
27    ///
28    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
29    ///
30    /// # Examples
31    /// ```
32    /// use malachite_base::num::arithmetic::traits::{Pow, SaturatingSub};
33    /// use malachite_base::num::basic::traits::Zero;
34    /// use malachite_nz::natural::Natural;
35    ///
36    /// assert_eq!(Natural::ZERO.saturating_sub(Natural::from(123u32)), 0);
37    /// assert_eq!(Natural::from(123u32).saturating_sub(Natural::ZERO), 123);
38    /// assert_eq!(
39    ///     Natural::from(456u32).saturating_sub(Natural::from(123u32)),
40    ///     333
41    /// );
42    /// assert_eq!(
43    ///     (Natural::from(10u32).pow(12) * Natural::from(3u32))
44    ///         .saturating_sub(Natural::from(10u32).pow(12)),
45    ///     2000000000000u64
46    /// );
47    /// ```
48    #[inline]
49    fn saturating_sub(self, other: Self) -> Self {
50        CheckedSub::checked_sub(self, other).unwrap_or(Self::ZERO)
51    }
52}
53
54impl<'a> SaturatingSub<&'a Self> for Natural {
55    type Output = Self;
56
57    /// Subtracts a [`Natural`] by another [`Natural`], taking the first by value and the second by
58    /// reference and returning 0 if the result is negative.
59    ///
60    /// $$
61    /// f(x, y) = \max(x - y, 0).
62    /// $$
63    ///
64    /// # Worst-case complexity
65    /// $T(n) = O(n)$
66    ///
67    /// $M(n) = O(1)$
68    ///
69    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
70    ///
71    /// # Examples
72    /// ```
73    /// use malachite_base::num::arithmetic::traits::{Pow, SaturatingSub};
74    /// use malachite_base::num::basic::traits::Zero;
75    /// use malachite_nz::natural::Natural;
76    ///
77    /// assert_eq!(Natural::ZERO.saturating_sub(&Natural::from(123u32)), 0);
78    /// assert_eq!(Natural::from(123u32).saturating_sub(&Natural::ZERO), 123);
79    /// assert_eq!(
80    ///     Natural::from(456u32).saturating_sub(&Natural::from(123u32)),
81    ///     333
82    /// );
83    /// assert_eq!(
84    ///     (Natural::from(10u32).pow(12) * Natural::from(3u32))
85    ///         .saturating_sub(&Natural::from(10u32).pow(12)),
86    ///     2000000000000u64
87    /// );
88    /// ```
89    #[inline]
90    fn saturating_sub(self, other: &'a Self) -> Self {
91        CheckedSub::checked_sub(self, other).unwrap_or(Self::ZERO)
92    }
93}
94
95impl SaturatingSub<Natural> for &Natural {
96    type Output = Natural;
97
98    /// Subtracts a [`Natural`] by another [`Natural`], taking the first by reference and the second
99    /// by value and returning 0 if the result is negative.
100    ///
101    /// $$
102    /// f(x, y) = \max(x - y, 0).
103    /// $$
104    ///
105    /// # Worst-case complexity
106    /// $T(n) = O(n)$
107    ///
108    /// $M(n) = O(n)$
109    ///
110    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
111    ///
112    /// # Examples
113    /// ```
114    /// use malachite_base::num::arithmetic::traits::{Pow, SaturatingSub};
115    /// use malachite_base::num::basic::traits::Zero;
116    /// use malachite_nz::natural::Natural;
117    ///
118    /// assert_eq!((&Natural::ZERO).saturating_sub(Natural::from(123u32)), 0);
119    /// assert_eq!((&Natural::from(123u32)).saturating_sub(Natural::ZERO), 123);
120    /// assert_eq!(
121    ///     (&Natural::from(456u32)).saturating_sub(Natural::from(123u32)),
122    ///     333
123    /// );
124    /// assert_eq!(
125    ///     (&(Natural::from(10u32).pow(12) * Natural::from(3u32)))
126    ///         .saturating_sub(Natural::from(10u32).pow(12)),
127    ///     2000000000000u64
128    /// );
129    /// ```
130    #[inline]
131    fn saturating_sub(self, other: Natural) -> Natural {
132        CheckedSub::checked_sub(self, other).unwrap_or(Natural::ZERO)
133    }
134}
135
136impl SaturatingSub<&Natural> for &Natural {
137    type Output = Natural;
138
139    /// Subtracts a [`Natural`] by another [`Natural`], taking both by reference and returning 0 if
140    /// the result is negative.
141    ///
142    /// $$
143    /// f(x, y) = \max(x - y, 0).
144    /// $$
145    ///
146    /// # Worst-case complexity
147    /// $T(n) = O(n)$
148    ///
149    /// $M(n) = O(1)$
150    ///
151    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
152    ///
153    /// # Examples
154    /// ```
155    /// use malachite_base::num::arithmetic::traits::{Pow, SaturatingSub};
156    /// use malachite_base::num::basic::traits::Zero;
157    /// use malachite_nz::natural::Natural;
158    ///
159    /// assert_eq!((&Natural::ZERO).saturating_sub(&Natural::from(123u32)), 0);
160    /// assert_eq!((&Natural::from(123u32)).saturating_sub(&Natural::ZERO), 123);
161    /// assert_eq!(
162    ///     (&Natural::from(456u32)).saturating_sub(&Natural::from(123u32)),
163    ///     333
164    /// );
165    /// assert_eq!(
166    ///     (&(Natural::from(10u32).pow(12) * Natural::from(3u32)))
167    ///         .saturating_sub(&Natural::from(10u32).pow(12)),
168    ///     2000000000000u64
169    /// );
170    /// ```
171    #[inline]
172    fn saturating_sub(self, other: &Natural) -> Natural {
173        CheckedSub::checked_sub(self, other).unwrap_or(Natural::ZERO)
174    }
175}
176
177impl SaturatingSubAssign<Self> for Natural {
178    /// Subtracts a [`Natural`] by another [`Natural`] in place, taking the [`Natural`] on the
179    /// right-hand side by value and setting the left-hand side to 0 if the result is negative.
180    ///
181    /// $$
182    /// x \gets \max(x - y, 0).
183    /// $$
184    ///
185    /// # Worst-case complexity
186    /// $T(n) = O(n)$
187    ///
188    /// $M(n) = O(1)$
189    ///
190    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
191    ///
192    /// # Panics
193    /// Panics if `other` is greater than `self`.
194    ///
195    /// # Examples
196    /// ```
197    /// use malachite_base::num::arithmetic::traits::SaturatingSubAssign;
198    /// use malachite_base::num::basic::traits::Zero;
199    /// use malachite_nz::natural::Natural;
200    ///
201    /// let mut x = Natural::from(123u32);
202    /// x.saturating_sub_assign(Natural::from(123u32));
203    /// assert_eq!(x, 0);
204    ///
205    /// let mut x = Natural::from(123u32);
206    /// x.saturating_sub_assign(Natural::ZERO);
207    /// assert_eq!(x, 123);
208    ///
209    /// let mut x = Natural::from(456u32);
210    /// x.saturating_sub_assign(Natural::from(123u32));
211    /// assert_eq!(x, 333);
212    ///
213    /// let mut x = Natural::from(123u32);
214    /// x.saturating_sub_assign(Natural::from(456u32));
215    /// assert_eq!(x, 0);
216    /// ```
217    #[inline]
218    fn saturating_sub_assign(&mut self, other: Self) {
219        if self.sub_assign_ref_no_panic(&other) {
220            *self = Self::ZERO;
221        }
222    }
223}
224
225impl<'a> SaturatingSubAssign<&'a Self> for Natural {
226    /// Subtracts a [`Natural`] by another [`Natural`] in place, taking the [`Natural`] on the
227    /// right-hand side by reference and setting the left-hand side to 0 if the result is negative.
228    ///
229    /// $$
230    /// x \gets \max(x - y, 0).
231    /// $$
232    ///
233    /// # Worst-case complexity
234    /// $T(n) = O(n)$
235    ///
236    /// $M(n) = O(n)$
237    ///
238    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
239    ///
240    /// # Panics
241    /// Panics if `other` is greater than `self`.
242    ///
243    /// # Examples
244    /// ```
245    /// use malachite_base::num::arithmetic::traits::SaturatingSubAssign;
246    /// use malachite_base::num::basic::traits::Zero;
247    /// use malachite_nz::natural::Natural;
248    ///
249    /// let mut x = Natural::from(123u32);
250    /// x.saturating_sub_assign(&Natural::from(123u32));
251    /// assert_eq!(x, 0);
252    ///
253    /// let mut x = Natural::from(123u32);
254    /// x.saturating_sub_assign(&Natural::ZERO);
255    /// assert_eq!(x, 123);
256    ///
257    /// let mut x = Natural::from(456u32);
258    /// x.saturating_sub_assign(&Natural::from(123u32));
259    /// assert_eq!(x, 333);
260    ///
261    /// let mut x = Natural::from(123u32);
262    /// x.saturating_sub_assign(&Natural::from(456u32));
263    /// assert_eq!(x, 0);
264    /// ```
265    #[inline]
266    fn saturating_sub_assign(&mut self, other: &'a Self) {
267        if self.sub_assign_ref_no_panic(other) {
268            *self = Self::ZERO;
269        }
270    }
271}