Skip to main content

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}