Skip to main content

malachite_nz/natural/arithmetic/
sub_mul.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5//      Copyright © 1992-1994, 1996, 2000, 2001, 2002, 2004, 2005, 2012 Free Software Foundation,
6//      Inc.
7//
8// This file is part of Malachite.
9//
10// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
11// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
12// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
13
14use crate::natural::Natural;
15use crate::natural::arithmetic::mul::limbs_mul;
16use crate::natural::arithmetic::sub::{limbs_sub_greater_in_place_left, limbs_sub_limb_in_place};
17use crate::natural::comparison::cmp::limbs_cmp;
18use crate::platform::{DoubleLimb, Limb};
19use alloc::vec::Vec;
20use core::cmp::Ordering::*;
21use core::fmt::Display;
22use malachite_base::num::arithmetic::traits::{
23    CheckedSubMul, SubMul, SubMulAssign, WrappingAddAssign,
24};
25use malachite_base::num::conversion::traits::SplitInHalf;
26
27// Given the limbs of two `Natural`s x and y, and a limb z, returns the limbs of x - y * z. If y * z
28// > x, `None` is returned.
29//
30// # Worst-case complexity
31// $T(n) = O(n)$
32//
33// $M(n) = O(n)$
34//
35// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
36//
37// # Panics
38// Panics if `xs` is shorter than `ys`.
39//
40// This is equivalent to `mpz_aorsmul_1` from `mpz/aorsmul_i.c`, GMP 6.2.1, where `w` and `x` are
41// positive, `sub` is negative, and `w` is returned instead of overwriting the first input.
42pub_crate_test! {limbs_sub_mul_limb_greater(
43    xs: &[Limb],
44    ys: &[Limb],
45    z: Limb
46) -> Option<Vec<Limb>> {
47    let ys_len = ys.len();
48    let mut result = xs.to_vec();
49    let borrow = limbs_sub_mul_limb_same_length_in_place_left(&mut result[..ys_len], ys, z);
50    if borrow == 0 {
51        Some(result)
52    } else if xs.len() == ys_len || limbs_sub_limb_in_place(&mut result[ys_len..], borrow) {
53        None
54    } else {
55        Some(result)
56    }
57}}
58
59// Given the equal-length limbs of two `Natural`s x and y, and a limb z, calculates x - y * z and
60// writes the limbs of the result to the first (left) input slice. If y * z > x, a nonzero borrow is
61// returned.
62//
63// # Worst-case complexity
64// $T(n) = O(n)$
65//
66// $M(n) = O(1)$
67//
68// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
69//
70// # Panics
71// Panics if `xs` and `ys` have different lengths.
72//
73// This is equivalent to `mpn_submul_1` from `mpn/generic/submul_1.c`, GMP 6.2.1.
74pub_crate_test! {limbs_sub_mul_limb_same_length_in_place_left(
75    xs: &mut [Limb],
76    ys: &[Limb],
77    z: Limb
78) -> Limb {
79    assert_eq!(xs.len(), ys.len());
80    let mut borrow = 0;
81    let z = DoubleLimb::from(z);
82    for (x, &y) in xs.iter_mut().zip(ys.iter()) {
83        let (upper, mut lower) = (DoubleLimb::from(y) * z).split_in_half();
84        lower.wrapping_add_assign(borrow);
85        if lower < borrow {
86            borrow = upper.wrapping_add(1);
87        } else {
88            borrow = upper;
89        }
90        lower = x.wrapping_sub(lower);
91        if lower > *x {
92            borrow.wrapping_add_assign(1);
93        }
94        *x = lower;
95    }
96    borrow
97}}
98
99// Given the limbs of two `Natural`s x and y, and a limb z, calculates x - y * z and writes the
100// limbs of the result to the first (left) input slice. If y * z > x, a nonzero borrow is returned.
101//
102// # Worst-case complexity
103// $T(n) = O(n)$
104//
105// $M(n) = O(1)$
106//
107// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
108//
109// # Panics
110// Panics if `xs` is shorter than `ys`.
111//
112// This is equivalent to `mpn_submul_1` from `mpn/generic/submul_1.c`, GMP 6.2.1, but where the
113// first input may be longer than the second.
114pub_crate_test! {limbs_sub_mul_limb_greater_in_place_left(
115    xs: &mut [Limb],
116    ys: &[Limb],
117    limb: Limb
118) -> Limb {
119    let (xs_lo, xs_hi) = xs.split_at_mut(ys.len());
120    let borrow = limbs_sub_mul_limb_same_length_in_place_left(xs_lo, ys, limb);
121    if borrow == 0 || xs_hi.is_empty() {
122        borrow
123    } else {
124        Limb::from(limbs_sub_limb_in_place(xs_hi, borrow))
125    }
126}}
127
128// Given the equal-length limbs of two `Natural`s x and y, and a limb z, calculates x - y * z and
129// writes the limbs of the result to the second (right) input slice. If y * z > x, a nonzero borrow
130// is returned.
131//
132// # Worst-case complexity
133// $T(n) = O(n)$
134//
135// $M(n) = O(1)$
136//
137// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
138//
139// # Panics
140// Panics if `xs` and `ys` have different lengths.
141//
142// This is equivalent to `mpz_aorsmul_1` from `mpz/aorsmul_i.c`, GMP 6.2.1, where `w` and `x` are
143// positive and have the same lengths, sub is negative, and the lowest limbs of the result are
144// written to the second input rather than the first.
145pub_crate_test! {limbs_sub_mul_limb_same_length_in_place_right(
146    xs: &[Limb],
147    ys: &mut [Limb],
148    z: Limb,
149) -> Limb {
150    assert_eq!(xs.len(), ys.len());
151    let mut borrow = 0;
152    let z = DoubleLimb::from(z);
153    for (&x, y) in xs.iter().zip(ys.iter_mut()) {
154        let (upper, mut lower) = (DoubleLimb::from(*y) * z).split_in_half();
155        lower.wrapping_add_assign(borrow);
156        if lower < borrow {
157            borrow = upper.wrapping_add(1);
158        } else {
159            borrow = upper;
160        }
161        lower = x.wrapping_sub(lower);
162        if lower > x {
163            borrow.wrapping_add_assign(1);
164        }
165        *y = lower;
166    }
167    borrow
168}}
169
170// Given the limbs of two `Natural`s x and y, and a limb z, calculates x - y * z and writes the
171// limbs of the result to the second (right) input `Vec`. If y * z > x, a nonzero borrow is
172// returned.
173
174// # Worst-case complexity
175// $T(n) = O(n)$
176//
177// $M(m) = O(m)$
178//
179// where $T$ is time, $M$ is additional memory, $n$ is `xs.len()`, and $m$ is `xs.len() - ys.len()`.
180//
181// # Panics
182// Panics if `xs` is shorter than `ys`.
183//
184// This is equivalent to `mpz_aorsmul_1` from `mpz/aorsmul_i.c`, GMP 6.2.1, where `w` and `x` are
185// positive, `sub` is negative, and the result is written to the second input rather than the first.
186pub_test! {limbs_sub_mul_limb_greater_in_place_right(
187    xs: &[Limb],
188    ys: &mut Vec<Limb>,
189    z: Limb
190) -> Limb {
191    let ys_len = ys.len();
192    let (xs_lo, xs_hi) = xs.split_at(ys_len);
193    let borrow = limbs_sub_mul_limb_same_length_in_place_right(xs_lo, ys, z);
194    if xs_hi.is_empty() {
195        borrow
196    } else {
197        ys.extend(&xs[ys_len..]);
198        if borrow == 0 {
199            0
200        } else {
201            Limb::from(limbs_sub_limb_in_place(&mut ys[ys_len..], borrow))
202        }
203    }
204}}
205
206// Given the limbs `xs`, `ys` and `zs` of three `Natural`s x, y, and z, returns the limbs of x - y
207// * z. If x < y * z, `None` is returned. `ys` and `zs` should have length at least 2, and the
208// length of `xs` should be at least `ys.len()` + `zs.len()` - 1 (if the latter condition is false,
209// the result would be `None` and there's no point in calling this function). None of the slices
210// should have any trailing zeros. The result, if it exists, will have no trailing zeros.
211//
212// # Worst-case complexity
213// $T(n, m) = O(m + n \log n \log\log n)$
214//
215// $M(n, m) = O(m + n \log n)$
216//
217// where $T$ is time, $M$ is additional memory, $n$ is `max(ys.len(), zs.len())`, and $m$ is
218// `xs.len()`.
219//
220// # Panics
221// Panics if `ys` or `zs` have fewer than two elements each, or if `xs.len()` < `ys.len()` +
222// `zs.len()` - 1.
223//
224// This is equivalent to `mpz_aorsmul` from `mpz/aorsmul.c`, GMP 6.2.1, where `w`, `x`, and `y` are
225// positive, `sub` is negative, negative results are converted to `None`, and `w` is returned
226// instead of overwriting the first input.
227pub_crate_test! {limbs_sub_mul(xs: &[Limb], ys: &[Limb], zs: &[Limb]) -> Option<Vec<Limb>> {
228    let mut xs = xs.to_vec();
229    if limbs_sub_mul_in_place_left(&mut xs, ys, zs) {
230        None
231    } else {
232        Some(xs)
233    }
234}}
235
236// Given the limbs `xs`, `ys` and `zs` of three `Natural`s x, y, and z, computes x - y * z. The
237// limbs of the result are written to `xs`. Returns whether a borrow (overflow) occurred: if x < y
238// * z, `true` is returned and the value of `xs` should be ignored. `ys` and `zs` should have
239// length at least 2, and the length of `xs` should be at least `ys.len()` + `zs.len()` - 1 (if the
240// latter condition is false, the result would be negative and there would be no point in calling
241// this function). None of the slices should have any trailing zeros. The result, if it exists, will
242// have no trailing zeros.
243//
244// # Worst-case complexity
245// $T(n, m) = O(m + n \log n \log\log n)$
246//
247// $M(n) = O(n \log n)$
248//
249// where $T$ is time, $M$ is additional memory, $n$ is `max(ys.len(), zs.len())`, and $m$ is
250// `xs.len()`.
251//
252// # Panics
253// Panics if `ys` or `zs` have fewer than two elements each, or if `xs.len() < ys.len() + zs.len()
254// - 1`.
255//
256// This is equivalent to `mpz_aorsmul` from `mpz/aorsmul.c`, GMP 6.2.1, where `w`, `x`, and `y` are
257// positive, `sub` is negative and negative results are discarded.
258pub_crate_test! {limbs_sub_mul_in_place_left(xs: &mut [Limb], ys: &[Limb], zs: &[Limb]) -> bool {
259    assert!(ys.len() > 1);
260    assert!(zs.len() > 1);
261    let mut scratch = limbs_mul(ys, zs);
262    assert!(xs.len() >= scratch.len() - 1);
263    if *scratch.last().unwrap() == 0 {
264        scratch.pop();
265    }
266    let borrow = limbs_cmp(xs, &scratch) == Less;
267    if !borrow {
268        assert!(!limbs_sub_greater_in_place_left(xs, &scratch));
269    }
270    borrow
271}}
272
273fn sub_mul_panic<S: Display, T: Display, U: Display>(a: S, b: T, c: U) -> ! {
274    panic!("Cannot perform sub_mul. a: {a}, b: {b}, c: {c}");
275}
276
277impl SubMul<Self, Self> for Natural {
278    type Output = Self;
279
280    /// Subtracts a [`Natural`] by the product of two other [`Natural`]s, taking all three by value.
281    ///
282    /// $$
283    /// f(x, y, z) = x - yz.
284    /// $$
285    ///
286    /// # Worst-case complexity
287    /// $T(n, m) = O(m + n \log n \log\log n)$
288    ///
289    /// $M(n) = O(n \log n)$
290    ///
291    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
292    /// z.significant_bits())`, and $m$ is `x.significant_bits()`.
293    ///
294    /// # Panics
295    /// Panics if `y * z` is greater than `self`.
296    ///
297    /// # Examples
298    /// ```
299    /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
300    /// use malachite_nz::natural::Natural;
301    ///
302    /// assert_eq!(
303    ///     Natural::from(20u32).sub_mul(Natural::from(3u32), Natural::from(4u32)),
304    ///     8
305    /// );
306    /// assert_eq!(
307    ///     Natural::from(10u32)
308    ///         .pow(12)
309    ///         .sub_mul(Natural::from(0x10000u32), Natural::from(0x10000u32)),
310    ///     995705032704u64
311    /// );
312    /// ```
313    fn sub_mul(self, y: Self, z: Self) -> Self {
314        self.checked_sub_mul(y, z)
315            .expect("Natural sub_mul_assign cannot have a negative result")
316    }
317}
318
319impl<'a> SubMul<Self, &'a Self> for Natural {
320    type Output = Self;
321
322    /// Subtracts a [`Natural`] by the product of two other [`Natural`]s, taking the first two by
323    /// value and the third by reference.
324    ///
325    /// $$
326    /// f(x, y, z) = x - yz.
327    /// $$
328    ///
329    /// # Worst-case complexity
330    /// $T(n, m) = O(m + n \log n \log\log n)$
331    ///
332    /// $M(n) = O(n \log n)$
333    ///
334    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
335    /// z.significant_bits())`, and $m$ is `x.significant_bits()`.
336    ///
337    /// # Panics
338    /// Panics if `y * z` is greater than `self`.
339    ///
340    /// # Examples
341    /// ```
342    /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
343    /// use malachite_nz::natural::Natural;
344    ///
345    /// assert_eq!(
346    ///     Natural::from(20u32).sub_mul(Natural::from(3u32), &Natural::from(4u32)),
347    ///     8
348    /// );
349    /// assert_eq!(
350    ///     Natural::from(10u32)
351    ///         .pow(12)
352    ///         .sub_mul(Natural::from(0x10000u32), &Natural::from(0x10000u32)),
353    ///     995705032704u64
354    /// );
355    /// ```
356    fn sub_mul(self, y: Self, z: &'a Self) -> Self {
357        self.checked_sub_mul(y, z)
358            .expect("Natural sub_mul_assign cannot have a negative result")
359    }
360}
361
362impl<'a> SubMul<&'a Self, Self> for Natural {
363    type Output = Self;
364
365    /// Subtracts a [`Natural`] by the product of two other [`Natural`]s, taking the first and third
366    /// by value and the second by reference.
367    ///
368    /// $$
369    /// f(x, y, z) = x - yz.
370    /// $$
371    ///
372    /// # Worst-case complexity
373    /// $T(n, m) = O(m + n \log n \log\log n)$
374    ///
375    /// $M(n) = O(n \log n)$
376    ///
377    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
378    /// z.significant_bits())`, and $m$ is `x.significant_bits()`.
379    ///
380    /// # Panics
381    /// Panics if `y * z` is greater than `self`.
382    ///
383    /// # Examples
384    /// ```
385    /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
386    /// use malachite_nz::natural::Natural;
387    ///
388    /// assert_eq!(
389    ///     Natural::from(20u32).sub_mul(&Natural::from(3u32), Natural::from(4u32)),
390    ///     8
391    /// );
392    /// assert_eq!(
393    ///     Natural::from(10u32)
394    ///         .pow(12)
395    ///         .sub_mul(&Natural::from(0x10000u32), Natural::from(0x10000u32)),
396    ///     995705032704u64
397    /// );
398    /// ```
399    fn sub_mul(self, y: &'a Self, z: Self) -> Self {
400        self.checked_sub_mul(y, z)
401            .expect("Natural sub_mul_assign cannot have a negative result")
402    }
403}
404
405impl<'a, 'b> SubMul<&'a Self, &'b Self> for Natural {
406    type Output = Self;
407
408    /// Subtracts a [`Natural`] by the product of two other [`Natural`]s, taking the first by value
409    /// and the second and third by reference.
410    ///
411    /// $$
412    /// f(x, y, z) = x - yz.
413    /// $$
414    ///
415    /// # Worst-case complexity
416    /// $T(n, m) = O(m + n \log n \log\log n)$
417    ///
418    /// $M(n) = O(n \log n)$
419    ///
420    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
421    /// z.significant_bits())`, and $m$ is `x.significant_bits()`.
422    ///
423    /// # Panics
424    /// Panics if `y * z` is greater than `self`.
425    ///
426    /// # Examples
427    /// ```
428    /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
429    /// use malachite_nz::natural::Natural;
430    ///
431    /// assert_eq!(
432    ///     Natural::from(20u32).sub_mul(&Natural::from(3u32), &Natural::from(4u32)),
433    ///     8
434    /// );
435    /// assert_eq!(
436    ///     Natural::from(10u32)
437    ///         .pow(12)
438    ///         .sub_mul(&Natural::from(0x10000u32), &Natural::from(0x10000u32)),
439    ///     995705032704u64
440    /// );
441    /// ```
442    fn sub_mul(self, y: &'a Self, z: &'b Self) -> Self {
443        self.checked_sub_mul(y, z)
444            .expect("Natural sub_mul_assign cannot have a negative result")
445    }
446}
447
448impl SubMul<&Natural, &Natural> for &Natural {
449    type Output = Natural;
450
451    /// Subtracts a [`Natural`] by the product of two other [`Natural`]s, taking all three by
452    /// reference.
453    ///
454    /// $$
455    /// f(x, y, z) = x - yz.
456    /// $$
457    ///
458    /// # Worst-case complexity
459    /// $T(n, m) = O(m + n \log n \log\log n)$
460    ///
461    /// $M(n, m) = O(m + n \log n)$
462    ///
463    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
464    /// z.significant_bits())`, and $m$ is `x.significant_bits()`.
465    ///
466    /// # Panics
467    /// Panics if `y * z` is greater than `self`.
468    ///
469    /// # Examples
470    /// ```
471    /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
472    /// use malachite_nz::natural::Natural;
473    ///
474    /// assert_eq!(
475    ///     (&Natural::from(20u32)).sub_mul(&Natural::from(3u32), &Natural::from(4u32)),
476    ///     8
477    /// );
478    /// assert_eq!(
479    ///     (&Natural::from(10u32).pow(12))
480    ///         .sub_mul(&Natural::from(0x10000u32), &Natural::from(0x10000u32)),
481    ///     995705032704u64
482    /// );
483    /// ```
484    fn sub_mul(self, y: &Natural, z: &Natural) -> Natural {
485        self.checked_sub_mul(y, z).unwrap_or_else(|| {
486            sub_mul_panic(self, y, z);
487        })
488    }
489}
490
491impl SubMulAssign<Self, Self> for Natural {
492    /// Subtracts a [`Natural`] by the product of two other [`Natural`]s in place, taking both
493    /// [`Natural`]s on the right-hand side by value.
494    ///
495    /// $$
496    /// x \gets x - yz.
497    /// $$
498    ///
499    /// # Worst-case complexity
500    /// $T(n, m) = O(m + n \log n \log\log n)$
501    ///
502    /// $M(n) = O(n \log n)$
503    ///
504    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
505    /// z.significant_bits())`, and $m$ is `x.significant_bits()`.
506    ///
507    /// # Panics
508    /// Panics if `y * z` is greater than `self`.
509    ///
510    /// # Examples
511    /// ```
512    /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
513    /// use malachite_nz::natural::Natural;
514    ///
515    /// let mut x = Natural::from(20u32);
516    /// x.sub_mul_assign(Natural::from(3u32), Natural::from(4u32));
517    /// assert_eq!(x, 8);
518    ///
519    /// let mut x = Natural::from(10u32).pow(12);
520    /// x.sub_mul_assign(Natural::from(0x10000u32), Natural::from(0x10000u32));
521    /// assert_eq!(x, 995705032704u64);
522    /// ```
523    fn sub_mul_assign(&mut self, y: Self, z: Self) {
524        assert!(
525            !self.sub_mul_assign_no_panic(y, z),
526            "Natural sub_mul_assign cannot have a negative result"
527        );
528    }
529}
530
531impl<'a> SubMulAssign<Self, &'a Self> for Natural {
532    /// Subtracts a [`Natural`] by the product of two other [`Natural`]s in place, taking the first
533    /// [`Natural`] on the right-hand side by value and the second by reference.
534    ///
535    /// $$
536    /// x \gets x - yz.
537    /// $$
538    ///
539    /// # Worst-case complexity
540    /// $T(n, m) = O(m + n \log n \log\log n)$
541    ///
542    /// $M(n) = O(n \log n)$
543    ///
544    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
545    /// z.significant_bits())`, and $m$ is `x.significant_bits()`.
546    ///
547    /// # Panics
548    /// Panics if `y * z` is greater than `self`.
549    ///
550    /// # Examples
551    /// ```
552    /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
553    /// use malachite_nz::natural::Natural;
554    ///
555    /// let mut x = Natural::from(20u32);
556    /// x.sub_mul_assign(Natural::from(3u32), &Natural::from(4u32));
557    /// assert_eq!(x, 8);
558    ///
559    /// let mut x = Natural::from(10u32).pow(12);
560    /// x.sub_mul_assign(Natural::from(0x10000u32), &Natural::from(0x10000u32));
561    /// assert_eq!(x, 995705032704u64);
562    /// ```
563    fn sub_mul_assign(&mut self, y: Self, z: &'a Self) {
564        assert!(
565            !self.sub_mul_assign_val_ref_no_panic(y, z),
566            "Natural sub_mul_assign cannot have a negative result"
567        );
568    }
569}
570
571impl<'a> SubMulAssign<&'a Self, Self> for Natural {
572    /// Subtracts a [`Natural`] by the product of two other [`Natural`]s in place, taking the first
573    /// [`Natural`] on the right-hand side by reference and the second by value.
574    ///
575    /// $$
576    /// x \gets x - yz.
577    /// $$
578    ///
579    /// # Worst-case complexity
580    /// $T(n, m) = O(m + n \log n \log\log n)$
581    ///
582    /// $M(n) = O(n \log n)$
583    ///
584    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
585    /// z.significant_bits())`, and $m$ is `x.significant_bits()`.
586    ///
587    /// # Panics
588    /// Panics if `y * z` is greater than `self`.
589    ///
590    /// # Examples
591    /// ```
592    /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
593    /// use malachite_nz::natural::Natural;
594    ///
595    /// let mut x = Natural::from(20u32);
596    /// x.sub_mul_assign(&Natural::from(3u32), Natural::from(4u32));
597    /// assert_eq!(x, 8);
598    ///
599    /// let mut x = Natural::from(10u32).pow(12);
600    /// x.sub_mul_assign(&Natural::from(0x10000u32), Natural::from(0x10000u32));
601    /// assert_eq!(x, 995705032704u64);
602    /// ```
603    fn sub_mul_assign(&mut self, y: &'a Self, z: Self) {
604        assert!(
605            !self.sub_mul_assign_ref_val_no_panic(y, z),
606            "Natural sub_mul_assign cannot have a negative result"
607        );
608    }
609}
610
611impl<'a, 'b> SubMulAssign<&'a Self, &'b Self> for Natural {
612    /// Subtracts a [`Natural`] by the product of two other [`Natural`]s in place, taking both
613    /// [`Natural`]s on the right-hand side by reference.
614    ///
615    /// $$
616    /// x \gets x - yz.
617    /// $$
618    ///
619    /// # Worst-case complexity
620    /// $T(n, m) = O(m + n \log n \log\log n)$
621    ///
622    /// $M(n) = O(n \log n)$
623    ///
624    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
625    /// z.significant_bits())`, and $m$ is `x.significant_bits()`.
626    ///
627    /// # Panics
628    /// Panics if `y * z` is greater than `self`.
629    ///
630    /// # Examples
631    /// ```
632    /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
633    /// use malachite_nz::natural::Natural;
634    ///
635    /// let mut x = Natural::from(20u32);
636    /// x.sub_mul_assign(&Natural::from(3u32), &Natural::from(4u32));
637    /// assert_eq!(x, 8);
638    ///
639    /// let mut x = Natural::from(10u32).pow(12);
640    /// x.sub_mul_assign(&Natural::from(0x10000u32), &Natural::from(0x10000u32));
641    /// assert_eq!(x, 995705032704u64);
642    /// ```
643    fn sub_mul_assign(&mut self, y: &'a Self, z: &'b Self) {
644        assert!(
645            !self.sub_mul_assign_ref_ref_no_panic(y, z),
646            "Natural sub_mul_assign cannot have a negative result"
647        );
648    }
649}