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}