malachite_nz/natural/arithmetic/sub.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Some optimizations contributed by florian1345.
4//
5// Uses code adopted from the GNU MP Library.
6//
7// Copyright © 1991-2018, 2020 Free Software Foundation, Inc.
8//
9// This file is part of Malachite.
10//
11// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
12// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
13// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
14
15use crate::natural::Natural;
16use crate::platform::Limb;
17use alloc::vec::Vec;
18use core::fmt::Display;
19use core::ops::{Sub, SubAssign};
20use malachite_base::num::arithmetic::traits::CheckedSub;
21use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
22
23// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, subtracts the
24// `Limb` from the `Natural`. Returns a pair consisting of the limbs of the result, and whether
25// there was a borrow left over; that is, whether the `Limb` was greater than the `Natural`.
26//
27// # Worst-case complexity
28// $T(n) = O(n)$
29//
30// $M(n) = O(n)$
31//
32// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
33//
34// This is equivalent to `mpn_sub_1` from `gmp.h`, GMP 6.2.1, where the result is returned.
35pub_crate_test! {limbs_sub_limb(xs: &[Limb], mut y: Limb) -> (Vec<Limb>, bool) {
36 let len = xs.len();
37 let mut out = Vec::with_capacity(len);
38 for i in 0..len {
39 let (diff, overflow) = xs[i].overflowing_sub(y);
40 out.push(diff);
41 if overflow {
42 y = 1;
43 } else {
44 y = 0;
45 out.extend_from_slice(&xs[i + 1..]);
46 break;
47 }
48 }
49 (out, y != 0)
50}}
51
52// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, subtracts the
53// `Limb` from the `Natural`, writing the `xs.len()` limbs of the result to an output slice. Returns
54// whether there was a borrow left over; that is, whether the `Limb` was greater than the `Natural`.
55// The output slice must be at least as long as the input slice.
56//
57// # Worst-case complexity
58// $T(n) = O(n)$
59//
60// $M(n) = O(1)$
61//
62// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
63//
64// # Panics
65// Panics if `out` is shorter than `xs`.
66//
67// This is equivalent to `mpn_sub_1` from `gmp.h`, GMP 6.2.1.
68pub_crate_test! {limbs_sub_limb_to_out(out: &mut [Limb], xs: &[Limb], mut y: Limb) -> bool {
69 let len = xs.len();
70 assert!(out.len() >= len);
71 for i in 0..len {
72 let overflow;
73 (out[i], overflow) = xs[i].overflowing_sub(y);
74 if overflow {
75 y = 1;
76 } else {
77 y = 0;
78 let copy_index = i + 1;
79 out[copy_index..len].copy_from_slice(&xs[copy_index..]);
80 break;
81 }
82 }
83 y != 0
84}}
85
86// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, subtracts the
87// `Limb` from the `Natural` and writes the limbs of the result to the input slice. Returns whether
88// there was a borrow left over; that is, whether the `Limb` was greater than the `Natural`.
89//
90// # Worst-case complexity
91// $T(n) = O(n)$
92//
93// $M(n) = O(1)$
94//
95// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
96//
97// This is equivalent to `mpn_add_1` from `gmp.h`, GMP 6.2.1, where the result is written to the
98// input slice.
99pub_crate_test! {limbs_sub_limb_in_place<T: PrimitiveUnsigned>(xs: &mut [T], mut y: T) -> bool {
100 for x in &mut *xs {
101 if x.overflowing_sub_assign(y) {
102 y = T::ONE;
103 } else {
104 return false;
105 }
106 }
107 y != T::ZERO
108}}
109
110#[inline]
111pub(crate) fn sub_with_carry(x: Limb, y: Limb, carry: Limb) -> (Limb, Limb) {
112 let result_no_carry = x.wrapping_sub(y);
113 let result = result_no_carry.wrapping_sub(carry);
114 let carry = Limb::from((result_no_carry > x) || (result > result_no_carry));
115 (result, carry)
116}
117
118// Interpreting a two slices of `Limb`s as the limbs (in ascending order) of two `Natural`s,
119// subtracts the second from the first. Returns a pair consisting of the limbs of the result, and
120// whether there was a borrow left over; that is, whether the second `Natural` was greater than the
121// first `Natural`. The first slice must be at least as long as the second.
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 `xs.len()`.
129//
130// # Panics
131// Panics if `xs` is shorter than `ys`.
132//
133// This is equivalent to `mpn_sub` from `gmp.h`, GMP 6.2.1, where the output is returned.
134pub_crate_test! {limbs_sub(xs: &[Limb], ys: &[Limb]) -> (Vec<Limb>, bool) {
135 let xs_len = xs.len();
136 let ys_len = ys.len();
137 assert!(xs_len >= ys_len);
138 let mut out = Vec::with_capacity(xs_len);
139 let mut carry = 0;
140 for (&x, &y) in xs.iter().zip(ys.iter()) {
141 let o;
142 (o, carry) = sub_with_carry(x, y, carry);
143 out.push(o);
144 }
145 let mut borrow = carry != 0;
146 if xs_len != ys_len {
147 out.extend_from_slice(&xs[ys_len..]);
148 if borrow {
149 borrow = limbs_sub_limb_in_place(&mut out[ys_len..], 1);
150 }
151 }
152 (out, borrow)
153}}
154
155// Interpreting a two equal-length slices of `Limb`s as the limbs (in ascending order) of two
156// `Natural`s, subtracts the second from the first, writing the `xs.len()` limbs of the result to an
157// output slice. Returns whether there was a borrow left over; that is, whether the second `Natural`
158// was greater than the first `Natural`. The output slice must be at least as long as either input
159// slice.
160//
161// # Worst-case complexity
162// $T(n) = O(n)$
163//
164// $M(n) = O(1)$
165//
166// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
167//
168// # Panics
169// Panics if `out` is shorter than `xs` or if `xs` and `ys` have different lengths.
170//
171// This is equivalent to `mpn_sub_n` from `gmp.h`, GMP 6.2.1.
172pub_crate_test! {limbs_sub_same_length_to_out(out: &mut [Limb], xs: &[Limb], ys: &[Limb]) -> bool {
173 let len = xs.len();
174 assert_eq!(len, ys.len());
175 assert!(out.len() >= len);
176 let mut carry = 0;
177
178 for (out, (&x, &y)) in out.iter_mut().zip(xs.iter().zip(ys.iter())) {
179 (*out, carry) = sub_with_carry(x, y, carry);
180 }
181
182 carry > 0
183}}
184
185// Interpreting a two slices of `Limb`s as the limbs (in ascending order) of two `Natural`s,
186// subtracts the second from the first, writing the `xs.len()` limbs of the result to an output
187// slice. Returns whether there was a borrow left over; that is, whether the second `Natural` was
188// greater than the first `Natural`. The output slice must be at least as long as the first input
189// slice and the first input slice must be at least as long as the second.
190//
191// # Worst-case complexity
192// $T(n) = O(n)$
193//
194// $M(n) = O(1)$
195//
196// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
197//
198// # Panics
199// Panics if `out` is shorter than `xs` or if `xs` is shorter than `ys`.
200//
201// This is equivalent to `mpn_sub` from `gmp.h`, GMP 6.2.1.
202pub_crate_test! {limbs_sub_greater_to_out(out: &mut [Limb], xs: &[Limb], ys: &[Limb]) -> bool {
203 let xs_len = xs.len();
204 let ys_len = ys.len();
205 assert!(out.len() >= xs_len);
206 let (xs_lo, xs_hi) = xs.split_at(ys_len);
207 let borrow = limbs_sub_same_length_to_out(out, xs_lo, ys);
208 if xs_len == ys_len {
209 borrow
210 } else if borrow {
211 limbs_sub_limb_to_out(&mut out[ys_len..], xs_hi, 1)
212 } else {
213 out[ys_len..xs_len].copy_from_slice(xs_hi);
214 false
215 }
216}}
217
218// Interpreting two equal-length slices of `Limb`s as the limbs (in ascending order) of two
219// `Natural`s, subtracts the second from the first, writing the `xs.len()` limbs of the result to
220// the first (left) slice. Returns whether there was a borrow left over; that is, whether the second
221// `Natural` was greater than the first `Natural`.
222//
223// # Worst-case complexity
224// $T(n) = O(n)$
225//
226// $M(n) = O(1)$
227//
228// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
229//
230// # Panics
231// Panics if `xs` and `ys` have different lengths.
232//
233// This is equivalent to `mpn_sub_n` from `gmp.h`, GMP 6.2.1, where the output is written to the
234// first input.
235pub_crate_test! {limbs_sub_same_length_in_place_left(xs: &mut [Limb], ys: &[Limb]) -> bool {
236 assert_eq!(xs.len(), ys.len());
237 let mut carry = 0;
238
239 for (x, &y) in xs.iter_mut().zip(ys.iter()) {
240 (*x, carry) = sub_with_carry(*x, y, carry);
241 }
242
243 carry > 0
244}}
245
246// Interpreting two slices of `Limb`s as the limbs (in ascending order) of two `Natural`s, subtracts
247// the second from the first, writing the `xs.len()` limbs of the result to the first (left) slice.
248// Returns whether there was a borrow left over; that is, whether the second `Natural` was greater
249// than the first `Natural`. The first slice must be at least as long as the second.
250//
251// # Worst-case complexity
252// $T(n) = O(n)$
253//
254// $M(n) = O(1)$
255//
256// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
257//
258// # Panics
259// Panics if `xs` is shorter than `ys`.
260//
261// This is equivalent to `mpn_sub` from `gmp.h`, GMP 6.2.1, where the output is written to the first
262// input.
263pub_crate_test! {limbs_sub_greater_in_place_left(xs: &mut [Limb], ys: &[Limb]) -> bool {
264 let xs_len = xs.len();
265 let ys_len = ys.len();
266 let (xs_lo, xs_hi) = xs.split_at_mut(ys_len);
267 let borrow = limbs_sub_same_length_in_place_left(xs_lo, ys);
268 if xs_len == ys_len {
269 borrow
270 } else if borrow {
271 limbs_sub_limb_in_place(xs_hi, 1)
272 } else {
273 false
274 }
275}}
276
277// Interpreting two equal-length slices of `Limb`s as the limbs (in ascending order) of two
278// `Natural`s, subtracts the second from the first, writing the `xs.len()` limbs of the result to
279// the second (right) slice. Returns whether there was a borrow left over; that is, whether the
280// second `Natural` was greater than the first `Natural`.
281//
282// # Worst-case complexity
283// $T(n) = O(n)$
284//
285// $M(n) = O(1)$
286//
287// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
288//
289// # Panics
290// Panics if `xs` and `ys` have different lengths.
291//
292// This is equivalent to `mpn_sub_n` from `gmp.h`, GMP 6.2.1, where the output is written to the
293// second input.
294pub_crate_test! {limbs_sub_same_length_in_place_right(xs: &[Limb], ys: &mut [Limb]) -> bool {
295 assert_eq!(xs.len(), ys.len());
296 let mut carry = 0;
297
298 for (&x, y) in xs.iter().zip(ys.iter_mut()) {
299 (*y, carry) = sub_with_carry(x, *y, carry);
300 }
301
302 carry > 0
303}}
304
305// Given two equal-length slices `xs` and `ys`, computes the difference between the `Natural`s whose
306// limbs are `xs` and `&ys[..len]`, and writes the limbs of the result to `ys`. Returns whether
307// there was a borrow left over; that is, whether the second `Natural` was greater than the first
308// `Natural`.
309//
310// # Worst-case complexity
311// $T(n) = O(n)$
312//
313// $M(n) = O(1)$
314//
315// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
316//
317// # Panics
318// Panics if `xs` and `ys` have different lengths or if `len` is greater than `xs.len()`.
319//
320// This is equivalent to `mpn_sub_n` from `gmp.h`, GMP 6.2.1, where the output is written to the
321// second input (which has `len` limbs) and the second input has enough space past `len` to
322// accomodate the output.
323pub_crate_test! {limbs_slice_sub_in_place_right(xs: &[Limb], ys: &mut [Limb], len: usize) -> bool {
324 let xs_len = xs.len();
325 assert_eq!(xs_len, ys.len());
326 let (xs_lo, xs_hi) = xs.split_at(len);
327 let (ys_lo, ys_hi) = ys.split_at_mut(len);
328 let borrow = limbs_sub_same_length_in_place_right(xs_lo, ys_lo);
329 if xs_len == len {
330 borrow
331 } else if borrow {
332 limbs_sub_limb_to_out(ys_hi, xs_hi, 1)
333 } else {
334 ys_hi.copy_from_slice(xs_hi);
335 false
336 }
337}}
338
339// Interpreting a of `Limb`s and a `Vec` of `Limb`s as the limbs (in ascending order) of two
340// `Natural`s, subtracts the second from the first, writing the `xs.len()` limbs of the result to
341// the `Vec`, possibly extending the `Vec`'s length. Returns whether there was a borrow left over;
342// that is, whether the second `Natural` was greater than the first `Natural`. The first slice must
343// be at least as long as the second.
344//
345// # Worst-case complexity
346// $T(n) = O(n)$
347//
348// $M(m) = O(m)$
349//
350// where $T$ is time, $M$ is additional memory, $n$ is `xs.len()`, and $m$ is `xs.len()` -
351// `ys.len()`.
352//
353// # Panics
354// Panics if `xs` is shorter than `ys`.
355pub_crate_test! {limbs_vec_sub_in_place_right(xs: &[Limb], ys: &mut Vec<Limb>) -> bool {
356 let xs_len = xs.len();
357 let ys_len = ys.len();
358 assert!(xs_len >= ys_len);
359 let (xs_lo, xs_hi) = xs.split_at(ys_len);
360 let borrow = limbs_sub_same_length_in_place_right(xs_lo, ys);
361 if xs_len == ys_len {
362 borrow
363 } else {
364 ys.extend_from_slice(xs_hi);
365 if borrow {
366 limbs_sub_limb_in_place(&mut ys[ys_len..], 1)
367 } else {
368 false
369 }
370 }
371}}
372
373// Given a slice `xs`, computes the difference between the `Natural`s whose limbs are
374// `&xs[..xs.len() - right_start]` and `&xs[right_start..]`, and writes the limbs of the result to
375// `&xs[..xs.len() - right_start]`. Returns whether there was a borrow left over; that is, whether
376// the second `Natural` was greater than the first `Natural`. As implied by the name, the input
377// slices may overlap.
378//
379// # Worst-case complexity
380// $T(n) = O(n)$
381//
382// $M(n) = O(1)$
383//
384// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len() - right_start`.
385//
386// # Panics
387// Panics if `right_start` is greater than `xs.len()`.
388//
389// This is equivalent to `mpn_sub_n` from `gmp.h`, GMP 6.2.1, where the output is written to the
390// first input, and the two inputs are possibly-overlapping subslices of a single slice.
391pub_crate_test! {limbs_sub_same_length_in_place_with_overlap(
392 xs: &mut [Limb],
393 right_start: usize
394) -> bool {
395 let len = xs.len() - right_start;
396 let mut carry = 0;
397 for i in 0..len {
398 (xs[i], carry) = sub_with_carry(xs[i], xs[i + right_start], carry);
399 }
400 carry != 0
401}}
402
403// Given two slices `xs` and `ys`, computes the difference between the `Natural`s whose limbs are
404// `&xs[xs.len() - ys.len()..]` and `&ys`, and writes the limbs of the result to `&xs[..ys.len()]`.
405// Returns whether there was a borrow left over; that is, whether the second `Natural` was greater
406// than the first `Natural`. As implied by the name, the input and output ranges may overlap. `xs`
407// must be at least as long as `ys`.
408//
409// # Worst-case complexity
410// $T(n) = O(n)$
411//
412// $M(n) = O(1)$
413//
414// where $T$ is time, $M$ is additional memory, and $n$ is `ys.len()`.
415//
416// # Panics
417// Panics if `xs.len()` is shorter than `ys.len()`.
418//
419// This is equivalent to `mpn_sub_n` from `gmp.h`, GMP 6.2.1, where the output is a prefix of a
420// slice and the left operand of the subtraction is a suffix of the same slice, and the prefix and
421// suffix may overlap.
422pub_crate_test! {limbs_sub_same_length_to_out_with_overlap(xs: &mut [Limb], ys: &[Limb]) -> bool {
423 let xs_len = xs.len();
424 let ys_len = ys.len();
425 assert!(xs_len >= ys_len);
426 let right_start = xs_len - ys_len;
427 let mut carry = 0;
428 for i in 0..ys_len {
429 (xs[i], carry) = sub_with_carry(xs[i + right_start], ys[i], carry);
430 }
431 carry != 0
432}}
433
434// Interpreting a two equal-length slices of `Limb`s as the limbs (in ascending order) of two
435// `Natural`s, subtracts the second from the first, and then subtracts a borrow (`false` is 0,
436// `true` is 1), writing the `xs.len()` limbs of the result to an output slice. Returns whether
437// there was a borrow left over. The output slice must be at least as long as either input slice.
438//
439// # Worst-case complexity
440// $T(n) = O(n)$
441//
442// $M(n) = O(1)$
443//
444// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
445//
446// # Panics
447// Panics if `out` is shorter than `xs` or if `xs` and `ys` have different lengths.
448//
449// This is equivalent to `mpn_sub_nc` from `gmp-impl.h`, GMP 6.2.1, where `rp`, `up`, and `vp` are
450// disjoint.
451pub_crate_test! {limbs_sub_same_length_with_borrow_in_to_out(
452 out: &mut [Limb],
453 xs: &[Limb],
454 ys: &[Limb],
455 borrow_in: bool,
456) -> bool {
457 let mut borrow = limbs_sub_same_length_to_out(out, xs, ys);
458 if borrow_in {
459 borrow |= limbs_sub_limb_in_place(&mut out[..xs.len()], 1);
460 }
461 borrow
462}}
463
464// Interpreting two equal-length slices of `Limb`s as the limbs (in ascending order) of two
465// `Natural`s, subtracts the second from the first, and then subtracts a borrow (`false` is 0,
466// `true` is 1), writing the `xs.len()` limbs of the result to the first (left) slice. Return
467// whether there was a borrow left over.
468//
469// # Worst-case complexity
470// $T(n) = O(n)$
471//
472// $M(n) = O(1)$
473//
474// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
475//
476// # Panics
477// Panics if `xs` and `ys` have different lengths.
478//
479// This is equivalent to `mpn_sub_nc` from `gmp-impl.h`, GMP 6.2.1, where `rp` is the same as `up`.
480pub_crate_test! {limbs_sub_same_length_with_borrow_in_in_place_left(
481 xs: &mut [Limb],
482 ys: &[Limb],
483 borrow_in: bool,
484) -> bool {
485 let mut borrow = limbs_sub_same_length_in_place_left(xs, ys);
486 if borrow_in {
487 borrow |= limbs_sub_limb_in_place(xs, 1);
488 }
489 borrow
490}}
491
492// Interpreting two equal-length slices of `Limb`s as the limbs (in ascending order) of two
493// `Natural`s, subtracts the second from the first, and then subtracts a borrow (`false` is 0,
494// `true` is 1), writing the `xs.len()` limbs of the result to the second (right) slice. Returns
495// whether there was a borrow left over.
496//
497// # Worst-case complexity
498// $T(n) = O(n)$
499//
500// $M(n) = O(1)$
501//
502// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
503//
504// # Panics
505// Panics if `xs` and `ys` have different lengths.
506//
507// This is equivalent to `mpn_sub_nc` from `gmp-impl.h`, GMP 6.2.1, where `rp` is the same as `vp`.
508pub_crate_test! {limbs_sub_same_length_with_borrow_in_in_place_right(
509 xs: &[Limb],
510 ys: &mut [Limb],
511 borrow_in: bool,
512) -> bool {
513 let mut borrow = limbs_sub_same_length_in_place_right(xs, ys);
514 if borrow_in {
515 borrow |= limbs_sub_limb_in_place(ys, 1);
516 }
517 borrow
518}}
519
520fn sub_panic<S: Display, T: Display>(x: S, y: T) -> ! {
521 panic!("Cannot subtract a number from a smaller number. self: {x}, other: {y}");
522}
523
524impl Natural {
525 pub(crate) fn sub_limb(self, other: Limb) -> Self {
526 self.checked_sub_limb(other)
527 .expect("Cannot subtract a Limb from a smaller Natural")
528 }
529
530 pub(crate) fn sub_limb_ref(&self, other: Limb) -> Self {
531 self.checked_sub_limb_ref(other).unwrap_or_else(|| {
532 sub_panic(self, other);
533 })
534 }
535
536 #[cfg(feature = "float_helpers")]
537 pub fn sub_assign_at_limb(&mut self, i: usize, y: Limb) {
538 if i == 0 {
539 *self -= Self::from(y);
540 return;
541 }
542 let xs = self.promote_in_place();
543 if xs.len() <= i {
544 xs.resize(i + 1, 0);
545 }
546 assert!(!limbs_sub_limb_in_place(&mut xs[i..], y));
547 self.trim();
548 }
549}
550
551impl Sub<Self> for Natural {
552 type Output = Self;
553
554 /// Subtracts a [`Natural`] by another [`Natural`], taking both by value.
555 ///
556 /// $$
557 /// f(x, y) = x - y.
558 /// $$
559 ///
560 /// # Worst-case complexity
561 /// $T(n) = O(n)$
562 ///
563 /// $M(n) = O(1)$
564 ///
565 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
566 ///
567 /// # Examples
568 /// ```
569 /// use malachite_base::num::arithmetic::traits::Pow;
570 /// use malachite_base::num::basic::traits::Zero;
571 /// use malachite_nz::natural::Natural;
572 ///
573 /// assert_eq!(Natural::from(123u32) - Natural::ZERO, 123);
574 /// assert_eq!(Natural::from(456u32) - Natural::from(123u32), 333);
575 /// assert_eq!(
576 /// Natural::from(10u32).pow(12) * Natural::from(3u32) - Natural::from(10u32).pow(12),
577 /// 2000000000000u64
578 /// );
579 /// ```
580 fn sub(self, other: Self) -> Self {
581 self.checked_sub(other)
582 .expect("Cannot subtract a Natural from a smaller Natural")
583 }
584}
585
586impl Sub<&Self> for Natural {
587 type Output = Self;
588
589 /// Subtracts a [`Natural`] by another [`Natural`], taking the first by value and the second by
590 /// reference.
591 ///
592 /// $$
593 /// f(x, y) = x - y.
594 /// $$
595 ///
596 /// # Worst-case complexity
597 /// $T(n) = O(n)$
598 ///
599 /// $M(n) = O(1)$
600 ///
601 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
602 ///
603 /// # Examples
604 /// ```
605 /// use malachite_base::num::arithmetic::traits::Pow;
606 /// use malachite_base::num::basic::traits::Zero;
607 /// use malachite_nz::natural::Natural;
608 ///
609 /// assert_eq!(Natural::from(123u32) - &Natural::ZERO, 123);
610 /// assert_eq!(Natural::from(456u32) - &Natural::from(123u32), 333);
611 /// assert_eq!(
612 /// Natural::from(10u32).pow(12) * Natural::from(3u32) - &Natural::from(10u32).pow(12),
613 /// 2000000000000u64
614 /// );
615 /// ```
616 fn sub(self, other: &Self) -> Self {
617 self.checked_sub(other)
618 .expect("Cannot subtract a Natural from a smaller Natural")
619 }
620}
621
622impl Sub<Natural> for &Natural {
623 type Output = Natural;
624
625 /// Subtracts a [`Natural`] by another [`Natural`], taking the first by reference and the second
626 /// by value.
627 ///
628 /// $$
629 /// f(x, y) = x - y.
630 /// $$
631 ///
632 /// # Worst-case complexity
633 /// $T(n) = O(n)$
634 ///
635 /// $M(n) = O(n)$
636 ///
637 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
638 ///
639 /// # Examples
640 /// ```
641 /// use malachite_base::num::arithmetic::traits::Pow;
642 /// use malachite_base::num::basic::traits::Zero;
643 /// use malachite_nz::natural::Natural;
644 ///
645 /// assert_eq!(&Natural::from(123u32) - Natural::ZERO, 123);
646 /// assert_eq!(&Natural::from(456u32) - Natural::from(123u32), 333);
647 /// assert_eq!(
648 /// &(Natural::from(10u32).pow(12) * Natural::from(3u32)) - Natural::from(10u32).pow(12),
649 /// 2000000000000u64
650 /// );
651 /// ```
652 fn sub(self, other: Natural) -> Natural {
653 self.checked_sub(other)
654 .expect("Cannot subtract a Natural from a smaller Natural")
655 }
656}
657
658impl Sub<&Natural> for &Natural {
659 type Output = Natural;
660
661 /// Subtracts a [`Natural`] by another [`Natural`], taking both by reference.
662 ///
663 /// $$
664 /// f(x, y) = x - y.
665 /// $$
666 ///
667 /// # Worst-case complexity
668 /// $T(n) = O(n)$
669 ///
670 /// $M(n) = O(n)$
671 ///
672 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
673 ///
674 /// # Examples
675 /// ```
676 /// use malachite_base::num::arithmetic::traits::Pow;
677 /// use malachite_base::num::basic::traits::Zero;
678 /// use malachite_nz::natural::Natural;
679 ///
680 /// assert_eq!(&Natural::from(123u32) - &Natural::ZERO, 123);
681 /// assert_eq!(&Natural::from(456u32) - &Natural::from(123u32), 333);
682 /// assert_eq!(
683 /// &(Natural::from(10u32).pow(12) * Natural::from(3u32)) - &Natural::from(10u32).pow(12),
684 /// 2000000000000u64
685 /// );
686 /// ```
687 fn sub(self, other: &Natural) -> Natural {
688 self.checked_sub(other).unwrap_or_else(|| {
689 sub_panic(self, other);
690 })
691 }
692}
693
694impl SubAssign<Self> for Natural {
695 /// Subtracts a [`Natural`] by another [`Natural`] in place, taking the [`Natural`] on the
696 /// right-hand side by value.
697 ///
698 /// $$
699 /// x \gets x - y.
700 /// $$
701 ///
702 /// # Worst-case complexity
703 /// $T(n) = O(n)$
704 ///
705 /// $M(n) = O(1)$
706 ///
707 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
708 ///
709 /// # Panics
710 /// Panics if `other` is greater than `self`.
711 ///
712 /// # Examples
713 /// ```
714 /// use malachite_base::num::arithmetic::traits::Pow;
715 /// use malachite_nz::natural::Natural;
716 ///
717 /// let mut x = Natural::from(10u32).pow(12) * Natural::from(10u32);
718 /// x -= Natural::from(10u32).pow(12);
719 /// x -= Natural::from(10u32).pow(12) * Natural::from(2u32);
720 /// x -= Natural::from(10u32).pow(12) * Natural::from(3u32);
721 /// x -= Natural::from(10u32).pow(12) * Natural::from(4u32);
722 /// assert_eq!(x, 0);
723 /// ```
724 fn sub_assign(&mut self, other: Self) {
725 assert!(
726 !self.sub_assign_no_panic(other),
727 "Cannot subtract a Natural from a smaller Natural"
728 );
729 }
730}
731
732impl SubAssign<&Self> for Natural {
733 /// Subtracts a [`Natural`] by another [`Natural`] in place, taking the [`Natural`] on the
734 /// right-hand side by reference.
735 ///
736 /// $$
737 /// x \gets x - y.
738 /// $$
739 ///
740 /// # Worst-case complexity
741 /// $T(n) = O(n)$
742 ///
743 /// $M(n) = O(1)$
744 ///
745 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
746 ///
747 /// # Panics
748 /// Panics if `other` is greater than `self`.
749 ///
750 /// # Examples
751 /// ```
752 /// use malachite_base::num::arithmetic::traits::Pow;
753 /// use malachite_nz::natural::Natural;
754 ///
755 /// let mut x = Natural::from(10u32).pow(12) * Natural::from(10u32);
756 /// x -= &Natural::from(10u32).pow(12);
757 /// x -= &(Natural::from(10u32).pow(12) * Natural::from(2u32));
758 /// x -= &(Natural::from(10u32).pow(12) * Natural::from(3u32));
759 /// x -= &(Natural::from(10u32).pow(12) * Natural::from(4u32));
760 /// assert_eq!(x, 0);
761 /// ```
762 fn sub_assign(&mut self, other: &Self) {
763 assert!(
764 !self.sub_assign_ref_no_panic(other),
765 "Cannot subtract a Natural from a smaller Natural"
766 );
767 }
768}