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}