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}