malachite_nz/integer/arithmetic/sub_mul.rs
1// Copyright © 2025 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.
52pub_crate_test! {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.
83pub_crate_test! {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.
168pub_test! {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.
248pub_crate_test! {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.
284pub_crate_test! {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.
311pub_crate_test! {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 let mut product = vec![0; product_len];
332 let mut mul_scratch = vec![0; limbs_mul_greater_to_out_scratch_len(ys.len(), zs.len())];
333 if limbs_mul_greater_to_out(&mut product, ys, zs, &mut mul_scratch) == 0 {
334 product.pop();
335 }
336 assert_ne!(*product.last().unwrap(), 0);
337 if limbs_cmp(xs, &product) == Less {
338 if xs_len < product_len {
339 xs.resize(product.len(), 0);
340 }
341 assert!(!limbs_slice_sub_in_place_right(
342 &product,
343 &mut xs[..product.len()],
344 xs_len,
345 ));
346 false
347 } else {
348 assert!(!limbs_sub_greater_in_place_left(xs, &product));
349 !slice_test_zero(xs)
350 }
351}
352
353impl SubMul<Self, Self> for Integer {
354 type Output = Self;
355
356 /// Subtracts an [`Integer`] by the product of two other [`Integer`]s, taking all three by
357 /// value.
358 ///
359 /// $f(x, y, z) = x - yz$.
360 ///
361 /// # Worst-case complexity
362 /// $T(n, m) = O(m + n \log n \log\log n)$
363 ///
364 /// $M(n) = O(n \log n)$
365 ///
366 /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
367 /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
368 ///
369 /// # Examples
370 /// ```
371 /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
372 /// use malachite_nz::integer::Integer;
373 ///
374 /// assert_eq!(
375 /// Integer::from(10u32).sub_mul(Integer::from(3u32), Integer::from(-4)),
376 /// 22
377 /// );
378 /// assert_eq!(
379 /// (-Integer::from(10u32).pow(12))
380 /// .sub_mul(Integer::from(-0x10000), -Integer::from(10u32).pow(12)),
381 /// -65537000000000000i64
382 /// );
383 /// ```
384 #[inline]
385 fn sub_mul(mut self, y: Self, z: Self) -> Self {
386 self.sub_mul_assign(y, z);
387 self
388 }
389}
390
391impl<'a> SubMul<Self, &'a Self> for Integer {
392 type Output = Self;
393
394 /// Subtracts an [`Integer`] by the product of two other [`Integer`]s, taking the first two by
395 /// value and the third by reference.
396 ///
397 /// $f(x, y, z) = x - yz$.
398 ///
399 /// # Worst-case complexity
400 /// $T(n, m) = O(m + n \log n \log\log n)$
401 ///
402 /// $M(n) = O(n \log n)$
403 ///
404 /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
405 /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
406 ///
407 /// # Examples
408 /// ```
409 /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
410 /// use malachite_nz::integer::Integer;
411 ///
412 /// assert_eq!(
413 /// Integer::from(10u32).sub_mul(Integer::from(3u32), &Integer::from(-4)),
414 /// 22
415 /// );
416 /// assert_eq!(
417 /// (-Integer::from(10u32).pow(12))
418 /// .sub_mul(Integer::from(-0x10000), &-Integer::from(10u32).pow(12)),
419 /// -65537000000000000i64
420 /// );
421 /// ```
422 #[inline]
423 fn sub_mul(mut self, y: Self, z: &'a Self) -> Self {
424 self.sub_mul_assign(y, z);
425 self
426 }
427}
428
429impl<'a> SubMul<&'a Self, Self> for Integer {
430 type Output = Self;
431
432 /// Subtracts an [`Integer`] by the product of two other [`Integer`]s, taking the first and
433 /// third by value and the second by reference.
434 ///
435 /// $f(x, y, z) = x - yz$.
436 ///
437 /// # Worst-case complexity
438 /// $T(n, m) = O(m + n \log n \log\log n)$
439 ///
440 /// $M(n) = O(n \log n)$
441 ///
442 /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
443 /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
444 ///
445 /// # Examples
446 /// ```
447 /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
448 /// use malachite_nz::integer::Integer;
449 ///
450 /// assert_eq!(
451 /// Integer::from(10u32).sub_mul(&Integer::from(3u32), Integer::from(-4)),
452 /// 22
453 /// );
454 /// assert_eq!(
455 /// (-Integer::from(10u32).pow(12))
456 /// .sub_mul(&Integer::from(-0x10000), -Integer::from(10u32).pow(12)),
457 /// -65537000000000000i64
458 /// );
459 /// ```
460 #[inline]
461 fn sub_mul(mut self, y: &'a Self, z: Self) -> Self {
462 self.sub_mul_assign(y, z);
463 self
464 }
465}
466
467impl SubMul<&Self, &Self> for Integer {
468 type Output = Self;
469
470 /// Subtracts an [`Integer`] by the product of two other [`Integer`]s, taking the first by value
471 /// and the second and third by reference.
472 ///
473 /// $f(x, y, z) = x - yz$.
474 ///
475 /// # Worst-case complexity
476 /// $T(n, m) = O(m + n \log n \log\log n)$
477 ///
478 /// $M(n) = O(n \log n)$
479 ///
480 /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
481 /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
482 ///
483 /// # Examples
484 /// ```
485 /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
486 /// use malachite_nz::integer::Integer;
487 ///
488 /// assert_eq!(
489 /// Integer::from(10u32).sub_mul(&Integer::from(3u32), &Integer::from(-4)),
490 /// 22
491 /// );
492 /// assert_eq!(
493 /// (-Integer::from(10u32).pow(12))
494 /// .sub_mul(&Integer::from(-0x10000), &-Integer::from(10u32).pow(12)),
495 /// -65537000000000000i64
496 /// );
497 /// ```
498 #[inline]
499 fn sub_mul(mut self, y: &Self, z: &Self) -> Self {
500 self.sub_mul_assign(y, z);
501 self
502 }
503}
504
505impl SubMul<&Integer, &Integer> for &Integer {
506 type Output = Integer;
507
508 /// Subtracts an [`Integer`] by the product of two other [`Integer`]s, taking all three by
509 /// reference.
510 ///
511 /// $f(x, y, z) = x - yz$.
512 ///
513 /// # Worst-case complexity
514 /// $T(n, m) = O(m + n \log n \log\log n)$
515 ///
516 /// $M(n, m) = O(m + n \log n)$
517 ///
518 /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
519 /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
520 ///
521 /// # Examples
522 /// ```
523 /// use malachite_base::num::arithmetic::traits::{Pow, SubMul};
524 /// use malachite_nz::integer::Integer;
525 ///
526 /// assert_eq!(
527 /// (&Integer::from(10u32)).sub_mul(&Integer::from(3u32), &Integer::from(-4)),
528 /// 22
529 /// );
530 /// assert_eq!(
531 /// (&-Integer::from(10u32).pow(12))
532 /// .sub_mul(&Integer::from(-0x10000), &-Integer::from(10u32).pow(12)),
533 /// -65537000000000000i64
534 /// );
535 /// ```
536 fn sub_mul(self, y: &Integer, z: &Integer) -> Integer {
537 if self.sign == (y.sign != z.sign) {
538 Integer {
539 sign: self.sign,
540 abs: (&self.abs).add_mul(&y.abs, &z.abs),
541 }
542 } else {
543 let (abs, abs_result_sign) = self.abs.add_mul_neg(&y.abs, &z.abs);
544 Integer {
545 sign: (self.sign == abs_result_sign) || abs == 0,
546 abs,
547 }
548 }
549 }
550}
551
552impl SubMulAssign<Self, Self> for Integer {
553 /// Subtracts the product of two other [`Integer`]s from an [`Integer`] in place, taking both
554 /// [`Integer`]s on the right-hand side by value.
555 ///
556 /// $x \gets x - yz$.
557 ///
558 /// # Worst-case complexity
559 /// $T(n, m) = O(m + n \log n \log\log n)$
560 ///
561 /// $M(n) = O(n \log n)$
562 ///
563 /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
564 /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
565 ///
566 /// # Examples
567 /// ```
568 /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
569 /// use malachite_nz::integer::Integer;
570 ///
571 /// let mut x = Integer::from(10u32);
572 /// x.sub_mul_assign(Integer::from(3u32), Integer::from(-4));
573 /// assert_eq!(x, 22);
574 ///
575 /// let mut x = -Integer::from(10u32).pow(12);
576 /// x.sub_mul_assign(Integer::from(-0x10000), -Integer::from(10u32).pow(12));
577 /// assert_eq!(x, -65537000000000000i64);
578 /// ```
579 fn sub_mul_assign(&mut self, y: Self, z: Self) {
580 self.add_mul_assign(-y, z);
581 }
582}
583
584impl<'a> SubMulAssign<Self, &'a Self> for Integer {
585 /// Subtracts the product of two other [`Integer`]s from an [`Integer`] in place, taking the
586 /// first [`Integer`] on the right-hand side by value and the second by reference.
587 ///
588 /// $x \gets x - yz$.
589 ///
590 /// # Worst-case complexity
591 /// $T(n, m) = O(m + n \log n \log\log n)$
592 ///
593 /// $M(n) = O(n \log n)$
594 ///
595 /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
596 /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
597 ///
598 /// # Examples
599 /// ```
600 /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
601 /// use malachite_nz::integer::Integer;
602 ///
603 /// let mut x = Integer::from(10u32);
604 /// x.sub_mul_assign(Integer::from(3u32), &Integer::from(-4));
605 /// assert_eq!(x, 22);
606 ///
607 /// let mut x = -Integer::from(10u32).pow(12);
608 /// x.sub_mul_assign(Integer::from(-0x10000), &(-Integer::from(10u32).pow(12)));
609 /// assert_eq!(x, -65537000000000000i64);
610 /// ```
611 fn sub_mul_assign(&mut self, y: Self, z: &'a Self) {
612 self.add_mul_assign(-y, z);
613 }
614}
615
616impl<'a> SubMulAssign<&'a Self, Self> for Integer {
617 /// Subtracts the product of two other [`Integer`]s from an [`Integer`] in place, taking the
618 /// first [`Integer`] on the right-hand side by reference and the second by value.
619 ///
620 /// $x \gets x + yz$.
621 ///
622 /// # Worst-case complexity
623 /// $T(n, m) = O(m + n \log n \log\log n)$
624 ///
625 /// $M(n) = O(n \log n)$
626 ///
627 /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
628 /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
629 ///
630 /// # Examples
631 /// ```
632 /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
633 /// use malachite_nz::integer::Integer;
634 ///
635 /// let mut x = Integer::from(10u32);
636 /// x.sub_mul_assign(&Integer::from(3u32), Integer::from(-4));
637 /// assert_eq!(x, 22);
638 ///
639 /// let mut x = -Integer::from(10u32).pow(12);
640 /// x.sub_mul_assign(&Integer::from(-0x10000), -Integer::from(10u32).pow(12));
641 /// assert_eq!(x, -65537000000000000i64);
642 /// ```
643 fn sub_mul_assign(&mut self, y: &'a Self, z: Self) {
644 self.add_mul_assign(y, -z);
645 }
646}
647
648impl<'a, 'b> SubMulAssign<&'a Self, &'b Self> for Integer {
649 /// Subtracts the product of two other [`Integer`]s from an [`Integer`] in place, taking both
650 /// [`Integer`]s on the right-hand side by reference.
651 ///
652 /// $x \gets x - yz$.
653 ///
654 /// # Worst-case complexity
655 /// $T(n, m) = O(m + n \log n \log\log n)$
656 ///
657 /// $M(n) = O(n \log n)$
658 ///
659 /// where $T$ is time, $M$ is additional memory, $n$ is `max(y.significant_bits(),
660 /// z.significant_bits())`, and $m$ is `self.significant_bits()`.
661 ///
662 /// # Examples
663 /// ```
664 /// use malachite_base::num::arithmetic::traits::{Pow, SubMulAssign};
665 /// use malachite_nz::integer::Integer;
666 ///
667 /// let mut x = Integer::from(10u32);
668 /// x.sub_mul_assign(&Integer::from(3u32), &Integer::from(-4));
669 /// assert_eq!(x, 22);
670 ///
671 /// let mut x = -Integer::from(10u32).pow(12);
672 /// x.sub_mul_assign(&Integer::from(-0x10000), &(-Integer::from(10u32).pow(12)));
673 /// assert_eq!(x, -65537000000000000i64);
674 /// ```
675 fn sub_mul_assign(&mut self, y: &'a Self, z: &'b Self) {
676 self.neg_assign();
677 self.add_mul_assign(y, z);
678 self.neg_assign();
679 }
680}