Skip to main content

malachite_nz/integer/arithmetic/
sub_mul.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5//      Copyright © 2001, 2004, 2005, 2012 Free Software Foundation, Inc.
6//
7// This file is part of Malachite.
8//
9// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
10// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
11// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
12
13use crate::integer::Integer;
14use crate::natural::arithmetic::add::limbs_slice_add_limb_in_place;
15use crate::natural::arithmetic::mul::limb::{
16    limbs_mul_limb_with_carry_to_out, limbs_slice_mul_limb_with_carry_in_place,
17};
18use crate::natural::arithmetic::mul::{
19    limbs_mul_greater_to_out, limbs_mul_greater_to_out_scratch_len,
20};
21use crate::natural::arithmetic::sub::{
22    limbs_slice_sub_in_place_right, limbs_sub_greater_in_place_left, limbs_sub_limb_in_place,
23    limbs_sub_limb_to_out,
24};
25use crate::natural::arithmetic::sub_mul::{
26    limbs_sub_mul_limb_same_length_in_place_left, limbs_sub_mul_limb_same_length_in_place_right,
27};
28use crate::natural::comparison::cmp::limbs_cmp;
29use crate::natural::logic::not::limbs_not_in_place;
30use crate::platform::{DoubleLimb, Limb};
31use alloc::vec::Vec;
32use core::cmp::Ordering::*;
33use malachite_base::num::arithmetic::traits::{
34    AddMul, AddMulAssign, NegAssign, SubMul, SubMulAssign, WrappingAddAssign, WrappingSubAssign,
35};
36use malachite_base::slices::slice_test_zero;
37
38// Given the limbs of two `Natural`s x and y, and a limb `z`, calculates x - y * z, returning the
39// limbs of the absolute value and the sign (true means non-negative). `xs` and `ys` should be
40// nonempty and have no trailing zeros, and `z` should be nonzero.
41//
42// # Worst-case complexity
43// $T(n) = O(n)$
44//
45// $M(n) = O(1)$
46//
47// where $T$ is time, $M$ is additional memory, and $n$ is `max(xs.len(), ys.len())`.
48//
49// This is equivalent to `mpz_aorsmul_1` from `mpz/aorsmul_i.c`, GMP 6.2.1, where `w` and `x` are
50// positive, `sub` is negative, and `w` is returned instead of overwriting the first input. `w_sign`
51// is also returned.
52crate_test_fn! {limbs_overflowing_sub_mul_limb(
53    xs: &[Limb],
54    ys: &[Limb],
55    z: Limb
56) -> (Vec<Limb>, bool) {
57    let mut result;
58    let sign = if xs.len() >= ys.len() {
59        result = xs.to_vec();
60        limbs_overflowing_sub_mul_limb_greater_in_place_left(&mut result, ys, z)
61    } else {
62        result = ys.to_vec();
63        limbs_overflowing_sub_mul_limb_smaller_in_place_right(xs, &mut result, z)
64    };
65    (result, sign)
66}}
67
68// Given the limbs of two `Natural`s x and y, and a limb `z`, calculates x - y * z, writing the
69// limbs of the absolute value to the first (left) slice and returning the sign (true means non-
70// negative). `xs` and `ys` should be nonempty and have no trailing zeros, and `z` should be
71// nonzero.
72//
73// # Worst-case complexity
74// $T(n) = O(n)$
75//
76// $M(m) = O(m)$
77//
78// where $T$ is time, $M$ is additional memory, $n$ is `max(xs.len(), ys.len())`, and $m$ is `max(1,
79// ys.len() - xs.len())`.
80//
81// This is equivalent to `mpz_aorsmul_1` from `mpz/aorsmul_i.c`, GMP 6.2.1, where `w` and `x` are
82// positive, `sub` is negative, and `w_sign` is returned.
83crate_test_fn! {limbs_overflowing_sub_mul_limb_in_place_left(
84    xs: &mut Vec<Limb>,
85    ys: &[Limb],
86    z: Limb,
87) -> bool {
88    let xs_len = xs.len();
89    let ys_len = ys.len();
90    if xs_len >= ys_len {
91        limbs_overflowing_sub_mul_limb_greater_in_place_left(xs, ys, z)
92    } else {
93        let (ys_lo, ys_hi) = ys.split_at(xs_len);
94        // submul of absolute values
95        let mut borrow = limbs_sub_mul_limb_same_length_in_place_left(xs, ys_lo, z);
96        // ys bigger than xs, so want ys * limb - xs. Submul has given xs - ys * limb, so take twos'
97        // complement and use an limbs_mul_limb_with_carry_to_out for the rest. -(-borrow * b ^ n +
98        // xs - ys * limb) = (borrow - 1) * b ^ n + ~(xs - ys * limb) + 1
99        limbs_not_in_place(xs);
100        if !limbs_slice_add_limb_in_place(xs, 1) {
101            borrow.wrapping_sub_assign(1);
102        }
103        // If borrow - 1 == -1, then hold that -1 for later.
104        // limbs_sub_mul_limb_same_length_in_place_left never returns borrow == Limb::MAX, so that
105        // value always indicates a -1.
106        let negative_one = borrow == Limb::MAX;
107        if negative_one {
108            borrow.wrapping_add_assign(1);
109        }
110        xs.resize(ys_len + 1, 0);
111        let xs_hi = &mut xs[xs_len..];
112        let (xs_hi_last, xs_hi_init) = xs_hi.split_last_mut().unwrap();
113        *xs_hi_last =
114            limbs_mul_limb_with_carry_to_out::<DoubleLimb, Limb>(xs_hi_init, ys_hi, z, borrow);
115        // Apply any -1 from above. The value at xs_hi is non-zero because z != 0 and the high limb
116        // of ys will be non-zero.
117        if negative_one {
118            assert!(!limbs_sub_limb_in_place(xs_hi, 1));
119        }
120        false
121    }
122}}
123
124// xs.len() >= ys.len()
125fn limbs_overflowing_sub_mul_limb_greater_in_place_left(
126    xs: &mut Vec<Limb>,
127    ys: &[Limb],
128    z: Limb,
129) -> bool {
130    let xs_len = xs.len();
131    let ys_len = ys.len();
132    xs.push(0);
133    // submul of absolute values
134    let (xs_lo, xs_hi) = xs.split_at_mut(ys_len);
135    let mut borrow = limbs_sub_mul_limb_same_length_in_place_left(xs_lo, ys, z);
136    // If xs bigger than ys, then propagate borrow through it.
137    if xs_len != ys_len {
138        borrow = Limb::from(limbs_sub_limb_in_place(xs_hi, borrow));
139    }
140    if borrow == 0 {
141        true
142    } else {
143        // Borrow out of xs, take twos' complement negative to get absolute value, flip sign of xs.
144        let (xs_last, xs_init) = xs.split_last_mut().unwrap();
145        *xs_last = borrow.wrapping_sub(1);
146        limbs_not_in_place(xs_init);
147        limbs_slice_add_limb_in_place(xs, 1);
148        false
149    }
150}
151
152// Given the limbs of two `Natural`s x and y, and a limb `z`, calculates x - y * z, writing the
153// limbs of the absolute value to the second (right) slice and returning the sign (true means non-
154// negative). `xs` and `ys` should be nonempty and have no trailing zeros, and `z` should be
155// nonzero.
156//
157// # Worst-case complexity
158// $T(n) = O(n)$
159//
160// $M(m) = O(m)$
161//
162// where $T$ is time, $M$ is additional memory, $n$ is `max(xs.len(), ys.len())`, and $m$ is `max(1,
163// ys.len() - xs.len())`.
164//
165// This is equivalent to `mpz_aorsmul_1` from `mpz/aorsmul_i.c`, GMP 6.2.1, where `w` and `x` are
166// positive, `sub` is negative, the limbs of the result are written to the second input rather than
167// the first, and `w_sign` is returned.
168private_test_fn! {limbs_overflowing_sub_mul_limb_in_place_right(
169    xs: &[Limb],
170    ys: &mut Vec<Limb>,
171    z: Limb,
172) -> bool {
173    let xs_len = xs.len();
174    let ys_len = ys.len();
175    if xs_len >= ys_len {
176        ys.resize(xs_len + 1, 0);
177        // submul of absolute values
178        let (xs_lo, xs_hi) = xs.split_at(ys_len);
179        let (ys_lo, ys_hi) = ys.split_at_mut(ys_len);
180        let mut borrow = limbs_sub_mul_limb_same_length_in_place_right(xs_lo, ys_lo, z);
181        // If xs bigger than ys, then propagate borrow through it.
182        if xs_len != ys_len {
183            borrow = Limb::from(limbs_sub_limb_to_out(ys_hi, xs_hi, borrow));
184        }
185        if borrow == 0 {
186            true
187        } else {
188            // Borrow out of ys, take twos' complement negative to get absolute value, flip sign of
189            // ys.
190            let (ys_last, ys_init) = ys.split_last_mut().unwrap();
191            *ys_last = borrow.wrapping_sub(1);
192            limbs_not_in_place(ys_init);
193            limbs_slice_add_limb_in_place(ys, 1);
194            false
195        }
196    } else {
197        limbs_overflowing_sub_mul_limb_smaller_in_place_right(xs, ys, z)
198    }
199}}
200
201// xs.len() < ys.len()
202fn limbs_overflowing_sub_mul_limb_smaller_in_place_right(
203    xs: &[Limb],
204    ys: &mut Vec<Limb>,
205    z: Limb,
206) -> bool {
207    ys.push(0);
208    let (ys_lo, ys_hi) = ys.split_at_mut(xs.len());
209    // submul of absolute values
210    let mut borrow = limbs_sub_mul_limb_same_length_in_place_right(xs, ys_lo, z);
211    // ys bigger than xs, so want ys * z - xs. Submul has given xs - ys * z, so take twos'
212    // complement and use an limbs_mul_limb_with_carry_to_out for the rest. -(-borrow * b ^ n + xs
213    // - ys * z) = (borrow - 1) * b ^ n + ~(xs - ys * z) + 1
214    limbs_not_in_place(ys_lo);
215    if !limbs_slice_add_limb_in_place(ys_lo, 1) {
216        borrow.wrapping_sub_assign(1);
217    }
218    // If borrow - 1 == -1, then hold that -1 for later.
219    // limbs_sub_mul_limb_same_length_in_place_left never returns borrow == Limb::MAX, so that value
220    // always indicates a -1.
221    let negative_one = borrow == Limb::MAX;
222    if negative_one {
223        borrow.wrapping_add_assign(1);
224    }
225    let (ys_hi_last, ys_hi_init) = ys_hi.split_last_mut().unwrap();
226    *ys_hi_last = limbs_slice_mul_limb_with_carry_in_place(ys_hi_init, z, borrow);
227    if negative_one {
228        assert!(!limbs_sub_limb_in_place(ys_hi, 1));
229    }
230    false
231}
232
233// Given the limbs of two `Natural`s x and y, and a limb `z`, calculates x - y * z, writing the
234// limbs of the absolute value to whichever input is longer. The first `bool` returned is `false` if
235// the result is written to the first input, and `true` if it is written to the second. The second
236// `bool` is the sign of the result (true means non-negative). `xs` and `ys` should be nonempty and
237// have no trailing zeros, and `z` should be nonzero.
238//
239// # Worst-case complexity
240// $T(n) = O(n)$
241//
242// $M(n) = O(1)$
243//
244// where $T$ is time, $M$ is additional memory, and $n$ is `max(xs.len(), ys.len())`.
245//
246// This is equivalent to `mpz_aorsmul_1` from `mpz/aorsmul_i.c`, GMP 6.2.1, where `w` and `x` are
247// positive, `sub` is negative, the result is written to the longer input, and `w_sign` is returned.
248crate_test_fn! {limbs_overflowing_sub_mul_limb_in_place_either(
249    xs: &mut Vec<Limb>,
250    ys: &mut Vec<Limb>,
251    z: Limb,
252) -> (bool, bool) {
253    if xs.len() >= ys.len() {
254        (
255            false,
256            limbs_overflowing_sub_mul_limb_greater_in_place_left(xs, ys, z),
257        )
258    } else {
259        (
260            true,
261            limbs_overflowing_sub_mul_limb_smaller_in_place_right(xs, ys, z),
262        )
263    }
264}}
265
266// Given the limbs of three `Natural`s x, y, and z, calculates x - y * z, returning the limbs of the
267// absolute value and the sign (true means non-negative). All of the input slices should be
268// non-empty and have no trailing zeros.
269//
270// # Worst-case complexity
271// $T(n, m) = O(m + n \log n \log\log n)$
272//
273// $M(n, m) = O(m + n \log n)$
274//
275// where $T$ is time, $M$ is additional memory, $n$ is `max(ys.len(), zs.len())`, and $m$ is
276// `xs.len()`.
277//
278// # Panics
279// Panics if `ys` or `zs` are empty.
280//
281// This is equivalent to `mpz_aorsmul` from `mpz/aorsmul.c`, GMP 6.2.1, where `w`, `x`, and `y` are
282// positive, `sub` is negative, and `w` is returned instead of overwriting the first input. `w_sign`
283// is also returned.
284crate_test_fn! {limbs_overflowing_sub_mul(
285    xs: &[Limb],
286    ys: &[Limb],
287    zs: &[Limb]
288) -> (Vec<Limb>, bool) {
289    let mut xs = xs.to_vec();
290    let sign = limbs_overflowing_sub_mul_in_place_left(&mut xs, ys, zs);
291    (xs, sign)
292}}
293
294// Given the limbs of three `Natural`s x, y, and z, calculates x - y * z, writing the limbs of the
295// absolute value to the first (left) slice and returning the sign (true means non-negative). All of
296// the input slices should be non-empty and have no trailing zeros.
297//
298// # Worst-case complexity
299// $T(n, m) = O(m + n \log n \log\log n)$
300//
301// $M(n, m) = O(n \log n)$
302//
303// where $T$ is time, $M$ is additional memory, $n$ is `max(ys.len(), zs.len())`, and $m$ is
304// `xs.len()`.
305//
306// # Panics
307// Panics if `ys` or `zs` are empty.
308//
309// This is equivalent to `mpz_aorsmul` from `mpz/aorsmul.c`, GMP 6.2.1, where `w`, `x`, and `y` are
310// positive, `sub` is negative, and `w_sign` is returned.
311crate_test_fn! {limbs_overflowing_sub_mul_in_place_left(
312    xs: &mut Vec<Limb>,
313    ys: &[Limb],
314    zs: &[Limb],
315) -> bool {
316    if ys.len() >= zs.len() {
317        limbs_overflowing_sub_mul_greater_in_place_left(xs, ys, zs)
318    } else {
319        limbs_overflowing_sub_mul_greater_in_place_left(xs, zs, ys)
320    }
321}}
322
323// zs.len() >= ys.len()
324fn limbs_overflowing_sub_mul_greater_in_place_left(
325    xs: &mut Vec<Limb>,
326    ys: &[Limb],
327    zs: &[Limb],
328) -> bool {
329    let xs_len = xs.len();
330    let product_len = ys.len() + zs.len();
331    // The product must end up owned, so it is the parent's prefix, with the multiplication scratch
332    // as the tail; the parent is truncated to the product once the multiplication is done.
333    let mut product =
334        vec![0; product_len + limbs_mul_greater_to_out_scratch_len(ys.len(), zs.len())];
335    let (product_slice, mul_scratch) = product.split_at_mut(product_len);
336    let high_zero = limbs_mul_greater_to_out(product_slice, ys, zs, mul_scratch) == 0;
337    product.truncate(product_len - usize::from(high_zero));
338    assert_ne!(*product.last().unwrap(), 0);
339    if limbs_cmp(xs, &product) == Less {
340        if xs_len < product_len {
341            xs.resize(product.len(), 0);
342        }
343        assert!(!limbs_slice_sub_in_place_right(
344            &product,
345            &mut xs[..product.len()],
346            xs_len,
347        ));
348        false
349    } else {
350        assert!(!limbs_sub_greater_in_place_left(xs, &product));
351        !slice_test_zero(xs)
352    }
353}
354
355impl SubMul<Self, Self> for Integer {
356    type Output = Self;
357
358    /// Subtracts an [`Integer`] by the product of two other [`Integer`]s, taking all three by
359    /// value.
360    ///
361    /// $f(x, y, z) = x - yz$.
362    ///
363    /// # Worst-case complexity
364    /// $T(n, m) = O(m + n \log n \log\log n)$
365    ///
366    /// $M(n) = O(n \log n)$
367    ///
368    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
369    /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
370    ///
371    /// # Examples
372    /// ```
373    /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
374    /// use malachite_nz::integer::Integer;
375    ///
376    /// assert_eq!(
377    ///     Integer::from(10u32).sub_mul(Integer::from(3u32), Integer::from(-4)),
378    ///     22
379    /// );
380    /// assert_eq!(
381    ///     (-Integer::from(10u32).pow(12))
382    ///         .sub_mul(Integer::from(-0x10000), -Integer::from(10u32).pow(12)),
383    ///     -65537000000000000i64
384    /// );
385    /// ```
386    #[inline]
387    fn sub_mul(mut self, y: Self, z: Self) -> Self {
388        self.sub_mul_assign(y, z);
389        self
390    }
391}
392
393impl<'a> SubMul<Self, &'a Self> for Integer {
394    type Output = Self;
395
396    /// Subtracts an [`Integer`] by the product of two other [`Integer`]s, taking the first two by
397    /// value and the third by reference.
398    ///
399    /// $f(x, y, z) = x - yz$.
400    ///
401    /// # Worst-case complexity
402    /// $T(n, m) = O(m + n \log n \log\log n)$
403    ///
404    /// $M(n) = O(n \log n)$
405    ///
406    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
407    /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
408    ///
409    /// # Examples
410    /// ```
411    /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
412    /// use malachite_nz::integer::Integer;
413    ///
414    /// assert_eq!(
415    ///     Integer::from(10u32).sub_mul(Integer::from(3u32), &Integer::from(-4)),
416    ///     22
417    /// );
418    /// assert_eq!(
419    ///     (-Integer::from(10u32).pow(12))
420    ///         .sub_mul(Integer::from(-0x10000), &-Integer::from(10u32).pow(12)),
421    ///     -65537000000000000i64
422    /// );
423    /// ```
424    #[inline]
425    fn sub_mul(mut self, y: Self, z: &'a Self) -> Self {
426        self.sub_mul_assign(y, z);
427        self
428    }
429}
430
431impl<'a> SubMul<&'a Self, Self> for Integer {
432    type Output = Self;
433
434    /// Subtracts an [`Integer`] by the product of two other [`Integer`]s, taking the first and
435    /// third by value and the second by reference.
436    ///
437    /// $f(x, y, z) = x - yz$.
438    ///
439    /// # Worst-case complexity
440    /// $T(n, m) = O(m + n \log n \log\log n)$
441    ///
442    /// $M(n) = O(n \log n)$
443    ///
444    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
445    /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
446    ///
447    /// # Examples
448    /// ```
449    /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
450    /// use malachite_nz::integer::Integer;
451    ///
452    /// assert_eq!(
453    ///     Integer::from(10u32).sub_mul(&Integer::from(3u32), Integer::from(-4)),
454    ///     22
455    /// );
456    /// assert_eq!(
457    ///     (-Integer::from(10u32).pow(12))
458    ///         .sub_mul(&Integer::from(-0x10000), -Integer::from(10u32).pow(12)),
459    ///     -65537000000000000i64
460    /// );
461    /// ```
462    #[inline]
463    fn sub_mul(mut self, y: &'a Self, z: Self) -> Self {
464        self.sub_mul_assign(y, z);
465        self
466    }
467}
468
469impl SubMul<&Self, &Self> for Integer {
470    type Output = Self;
471
472    /// Subtracts an [`Integer`] by the product of two other [`Integer`]s, taking the first by value
473    /// and the second and third by reference.
474    ///
475    /// $f(x, y, z) = x - yz$.
476    ///
477    /// # Worst-case complexity
478    /// $T(n, m) = O(m + n \log n \log\log n)$
479    ///
480    /// $M(n) = O(n \log n)$
481    ///
482    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
483    /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
484    ///
485    /// # Examples
486    /// ```
487    /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
488    /// use malachite_nz::integer::Integer;
489    ///
490    /// assert_eq!(
491    ///     Integer::from(10u32).sub_mul(&Integer::from(3u32), &Integer::from(-4)),
492    ///     22
493    /// );
494    /// assert_eq!(
495    ///     (-Integer::from(10u32).pow(12))
496    ///         .sub_mul(&Integer::from(-0x10000), &-Integer::from(10u32).pow(12)),
497    ///     -65537000000000000i64
498    /// );
499    /// ```
500    #[inline]
501    fn sub_mul(mut self, y: &Self, z: &Self) -> Self {
502        self.sub_mul_assign(y, z);
503        self
504    }
505}
506
507impl SubMul<&Integer, &Integer> for &Integer {
508    type Output = Integer;
509
510    /// Subtracts an [`Integer`] by the product of two other [`Integer`]s, taking all three by
511    /// reference.
512    ///
513    /// $f(x, y, z) = x - yz$.
514    ///
515    /// # Worst-case complexity
516    /// $T(n, m) = O(m + n \log n \log\log n)$
517    ///
518    /// $M(n, m) = O(m + n \log n)$
519    ///
520    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
521    /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
522    ///
523    /// # Examples
524    /// ```
525    /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
526    /// use malachite_nz::integer::Integer;
527    ///
528    /// assert_eq!(
529    ///     (&Integer::from(10u32)).sub_mul(&Integer::from(3u32), &Integer::from(-4)),
530    ///     22
531    /// );
532    /// assert_eq!(
533    ///     (&-Integer::from(10u32).pow(12))
534    ///         .sub_mul(&Integer::from(-0x10000), &-Integer::from(10u32).pow(12)),
535    ///     -65537000000000000i64
536    /// );
537    /// ```
538    fn sub_mul(self, y: &Integer, z: &Integer) -> Integer {
539        if self.sign == (y.sign != z.sign) {
540            Integer {
541                sign: self.sign,
542                abs: (&self.abs).add_mul(&y.abs, &z.abs),
543            }
544        } else {
545            let (abs, abs_result_sign) = self.abs.add_mul_neg(&y.abs, &z.abs);
546            Integer {
547                sign: (self.sign == abs_result_sign) || abs == 0u32,
548                abs,
549            }
550        }
551    }
552}
553
554impl SubMulAssign<Self, Self> for Integer {
555    /// Subtracts the product of two other [`Integer`]s from an [`Integer`] in place, taking both
556    /// [`Integer`]s on the right-hand side by value.
557    ///
558    /// $x \gets x - yz$.
559    ///
560    /// # Worst-case complexity
561    /// $T(n, m) = O(m + n \log n \log\log n)$
562    ///
563    /// $M(n) = O(n \log n)$
564    ///
565    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
566    /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
567    ///
568    /// # Examples
569    /// ```
570    /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
571    /// use malachite_nz::integer::Integer;
572    ///
573    /// let mut x = Integer::from(10u32);
574    /// x.sub_mul_assign(Integer::from(3u32), Integer::from(-4));
575    /// assert_eq!(x, 22);
576    ///
577    /// let mut x = -Integer::from(10u32).pow(12);
578    /// x.sub_mul_assign(Integer::from(-0x10000), -Integer::from(10u32).pow(12));
579    /// assert_eq!(x, -65537000000000000i64);
580    /// ```
581    fn sub_mul_assign(&mut self, y: Self, z: Self) {
582        self.add_mul_assign(-y, z);
583    }
584}
585
586impl<'a> SubMulAssign<Self, &'a Self> for Integer {
587    /// Subtracts the product of two other [`Integer`]s from an [`Integer`] in place, taking the
588    /// first [`Integer`] on the right-hand side by value and the second by reference.
589    ///
590    /// $x \gets x - yz$.
591    ///
592    /// # Worst-case complexity
593    /// $T(n, m) = O(m + n \log n \log\log n)$
594    ///
595    /// $M(n) = O(n \log n)$
596    ///
597    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
598    /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
599    ///
600    /// # Examples
601    /// ```
602    /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
603    /// use malachite_nz::integer::Integer;
604    ///
605    /// let mut x = Integer::from(10u32);
606    /// x.sub_mul_assign(Integer::from(3u32), &Integer::from(-4));
607    /// assert_eq!(x, 22);
608    ///
609    /// let mut x = -Integer::from(10u32).pow(12);
610    /// x.sub_mul_assign(Integer::from(-0x10000), &(-Integer::from(10u32).pow(12)));
611    /// assert_eq!(x, -65537000000000000i64);
612    /// ```
613    fn sub_mul_assign(&mut self, y: Self, z: &'a Self) {
614        self.add_mul_assign(-y, z);
615    }
616}
617
618impl<'a> SubMulAssign<&'a Self, Self> for Integer {
619    /// Subtracts the product of two other [`Integer`]s from an [`Integer`] in place, taking the
620    /// first [`Integer`] on the right-hand side by reference and the second by value.
621    ///
622    /// $x \gets x + yz$.
623    ///
624    /// # Worst-case complexity
625    /// $T(n, m) = O(m + n \log n \log\log n)$
626    ///
627    /// $M(n) = O(n \log n)$
628    ///
629    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
630    /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
631    ///
632    /// # Examples
633    /// ```
634    /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
635    /// use malachite_nz::integer::Integer;
636    ///
637    /// let mut x = Integer::from(10u32);
638    /// x.sub_mul_assign(&Integer::from(3u32), Integer::from(-4));
639    /// assert_eq!(x, 22);
640    ///
641    /// let mut x = -Integer::from(10u32).pow(12);
642    /// x.sub_mul_assign(&Integer::from(-0x10000), -Integer::from(10u32).pow(12));
643    /// assert_eq!(x, -65537000000000000i64);
644    /// ```
645    fn sub_mul_assign(&mut self, y: &'a Self, z: Self) {
646        self.add_mul_assign(y, -z);
647    }
648}
649
650impl<'a, 'b> SubMulAssign<&'a Self, &'b Self> for Integer {
651    /// Subtracts the product of two other [`Integer`]s from an [`Integer`] in place, taking both
652    /// [`Integer`]s on the right-hand side by reference.
653    ///
654    /// $x \gets x - yz$.
655    ///
656    /// # Worst-case complexity
657    /// $T(n, m) = O(m + n \log n \log\log n)$
658    ///
659    /// $M(n) = O(n \log n)$
660    ///
661    /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
662    /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
663    ///
664    /// # Examples
665    /// ```
666    /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
667    /// use malachite_nz::integer::Integer;
668    ///
669    /// let mut x = Integer::from(10u32);
670    /// x.sub_mul_assign(&Integer::from(3u32), &Integer::from(-4));
671    /// assert_eq!(x, 22);
672    ///
673    /// let mut x = -Integer::from(10u32).pow(12);
674    /// x.sub_mul_assign(&Integer::from(-0x10000), &(-Integer::from(10u32).pow(12)));
675    /// assert_eq!(x, -65537000000000000i64);
676    /// ```
677    fn sub_mul_assign(&mut self, y: &'a Self, z: &'b Self) {
678        self.neg_assign();
679        self.add_mul_assign(y, z);
680        self.neg_assign();
681    }
682}