Skip to main content

malachite_nz/integer/arithmetic/
mul_sub_mul.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::integer::Integer;
10use malachite_base::num::arithmetic::traits::{MulSubMul, MulSubMulAssign, SubMul, SubMulAssign};
11
12impl MulSubMul<Self, Self, Self> for Integer {
13    type Output = Self;
14
15    /// Subtracts the product of one pair of [`Integer`]s from the product of another, taking all
16    /// four by value.
17    ///
18    /// $f(x, y, z, w) = xy - zw$.
19    ///
20    /// # Worst-case complexity
21    /// $T(n) = O(n \log n \log\log n)$
22    ///
23    /// $M(n) = O(n \log n)$
24    ///
25    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
26    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
27    ///
28    /// # Examples
29    /// ```
30    /// use malachite_base::num::arithmetic::traits::MulSubMul;
31    /// use malachite_nz::integer::Integer;
32    ///
33    /// assert_eq!(
34    ///     Integer::from(-10).mul_sub_mul(Integer::from(3), Integer::from(4), Integer::from(5)),
35    ///     -50
36    /// );
37    /// ```
38    #[inline]
39    fn mul_sub_mul(self, y: Self, z: Self, w: Self) -> Self {
40        (self * y).sub_mul(z, w)
41    }
42}
43
44impl MulSubMul<Self, Self, &Self> for Integer {
45    type Output = Self;
46
47    /// Subtracts the product of one pair of [`Integer`]s from the product of another, taking $x$,
48    /// $y$ and $z$ by value and $w$ by reference.
49    ///
50    /// $f(x, y, z, w) = xy - zw$.
51    ///
52    /// # Worst-case complexity
53    /// $T(n) = O(n \log n \log\log n)$
54    ///
55    /// $M(n) = O(n \log n)$
56    ///
57    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
58    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
59    ///
60    /// # Examples
61    /// ```
62    /// use malachite_base::num::arithmetic::traits::MulSubMul;
63    /// use malachite_nz::integer::Integer;
64    ///
65    /// assert_eq!(
66    ///     Integer::from(-10).mul_sub_mul(Integer::from(3), Integer::from(4), &Integer::from(5)),
67    ///     -50
68    /// );
69    /// ```
70    #[inline]
71    fn mul_sub_mul(self, y: Self, z: Self, w: &Self) -> Self {
72        (self * y).sub_mul(z, w)
73    }
74}
75
76impl MulSubMul<Self, &Self, Self> for Integer {
77    type Output = Self;
78
79    /// Subtracts the product of one pair of [`Integer`]s from the product of another, taking $x$,
80    /// $y$ and $w$ by value and $z$ by reference.
81    ///
82    /// $f(x, y, z, w) = xy - zw$.
83    ///
84    /// # Worst-case complexity
85    /// $T(n) = O(n \log n \log\log n)$
86    ///
87    /// $M(n) = O(n \log n)$
88    ///
89    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
90    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
91    ///
92    /// # Examples
93    /// ```
94    /// use malachite_base::num::arithmetic::traits::MulSubMul;
95    /// use malachite_nz::integer::Integer;
96    ///
97    /// assert_eq!(
98    ///     Integer::from(-10).mul_sub_mul(Integer::from(3), &Integer::from(4), Integer::from(5)),
99    ///     -50
100    /// );
101    /// ```
102    #[inline]
103    fn mul_sub_mul(self, y: Self, z: &Self, w: Self) -> Self {
104        (self * y).sub_mul(z, w)
105    }
106}
107
108impl MulSubMul<Self, &Self, &Self> for Integer {
109    type Output = Self;
110
111    /// Subtracts the product of one pair of [`Integer`]s from the product of another, taking $x$
112    /// and $y$ by value and $z$ and $w$ by reference.
113    ///
114    /// $f(x, y, z, w) = xy - zw$.
115    ///
116    /// # Worst-case complexity
117    /// $T(n) = O(n \log n \log\log n)$
118    ///
119    /// $M(n) = O(n \log n)$
120    ///
121    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
122    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
123    ///
124    /// # Examples
125    /// ```
126    /// use malachite_base::num::arithmetic::traits::MulSubMul;
127    /// use malachite_nz::integer::Integer;
128    ///
129    /// assert_eq!(
130    ///     Integer::from(-10).mul_sub_mul(Integer::from(3), &Integer::from(4), &Integer::from(5)),
131    ///     -50
132    /// );
133    /// ```
134    #[inline]
135    fn mul_sub_mul(self, y: Self, z: &Self, w: &Self) -> Self {
136        (self * y).sub_mul(z, w)
137    }
138}
139
140impl MulSubMul<&Self, Self, Self> for Integer {
141    type Output = Self;
142
143    /// Subtracts the product of one pair of [`Integer`]s from the product of another, taking $x$,
144    /// $z$ and $w$ by value and $y$ by reference.
145    ///
146    /// $f(x, y, z, w) = xy - zw$.
147    ///
148    /// # Worst-case complexity
149    /// $T(n) = O(n \log n \log\log n)$
150    ///
151    /// $M(n) = O(n \log n)$
152    ///
153    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
154    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
155    ///
156    /// # Examples
157    /// ```
158    /// use malachite_base::num::arithmetic::traits::MulSubMul;
159    /// use malachite_nz::integer::Integer;
160    ///
161    /// assert_eq!(
162    ///     Integer::from(-10).mul_sub_mul(&Integer::from(3), Integer::from(4), Integer::from(5)),
163    ///     -50
164    /// );
165    /// ```
166    #[inline]
167    fn mul_sub_mul(self, y: &Self, z: Self, w: Self) -> Self {
168        (self * y).sub_mul(z, w)
169    }
170}
171
172impl MulSubMul<&Self, Self, &Self> for Integer {
173    type Output = Self;
174
175    /// Subtracts the product of one pair of [`Integer`]s from the product of another, taking $x$
176    /// and $z$ by value and $y$ and $w$ by reference.
177    ///
178    /// $f(x, y, z, w) = xy - zw$.
179    ///
180    /// # Worst-case complexity
181    /// $T(n) = O(n \log n \log\log n)$
182    ///
183    /// $M(n) = O(n \log n)$
184    ///
185    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
186    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
187    ///
188    /// # Examples
189    /// ```
190    /// use malachite_base::num::arithmetic::traits::MulSubMul;
191    /// use malachite_nz::integer::Integer;
192    ///
193    /// assert_eq!(
194    ///     Integer::from(-10).mul_sub_mul(&Integer::from(3), Integer::from(4), &Integer::from(5)),
195    ///     -50
196    /// );
197    /// ```
198    #[inline]
199    fn mul_sub_mul(self, y: &Self, z: Self, w: &Self) -> Self {
200        (self * y).sub_mul(z, w)
201    }
202}
203
204impl MulSubMul<&Self, &Self, Self> for Integer {
205    type Output = Self;
206
207    /// Subtracts the product of one pair of [`Integer`]s from the product of another, taking $x$
208    /// and $w$ by value and $y$ and $z$ by reference.
209    ///
210    /// $f(x, y, z, w) = xy - zw$.
211    ///
212    /// # Worst-case complexity
213    /// $T(n) = O(n \log n \log\log n)$
214    ///
215    /// $M(n) = O(n \log n)$
216    ///
217    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
218    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
219    ///
220    /// # Examples
221    /// ```
222    /// use malachite_base::num::arithmetic::traits::MulSubMul;
223    /// use malachite_nz::integer::Integer;
224    ///
225    /// assert_eq!(
226    ///     Integer::from(-10).mul_sub_mul(&Integer::from(3), &Integer::from(4), Integer::from(5)),
227    ///     -50
228    /// );
229    /// ```
230    #[inline]
231    fn mul_sub_mul(self, y: &Self, z: &Self, w: Self) -> Self {
232        (self * y).sub_mul(z, w)
233    }
234}
235
236impl MulSubMul<&Self, &Self, &Self> for Integer {
237    type Output = Self;
238
239    /// Subtracts the product of one pair of [`Integer`]s from the product of another, taking $x$ by
240    /// value and $y$, $z$ and $w$ by reference.
241    ///
242    /// $f(x, y, z, w) = xy - zw$.
243    ///
244    /// # Worst-case complexity
245    /// $T(n) = O(n \log n \log\log n)$
246    ///
247    /// $M(n) = O(n \log n)$
248    ///
249    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
250    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
251    ///
252    /// # Examples
253    /// ```
254    /// use malachite_base::num::arithmetic::traits::MulSubMul;
255    /// use malachite_nz::integer::Integer;
256    ///
257    /// assert_eq!(
258    ///     Integer::from(-10).mul_sub_mul(&Integer::from(3), &Integer::from(4), &Integer::from(5)),
259    ///     -50
260    /// );
261    /// ```
262    #[inline]
263    fn mul_sub_mul(self, y: &Self, z: &Self, w: &Self) -> Self {
264        (self * y).sub_mul(z, w)
265    }
266}
267
268impl MulSubMul<&Integer, &Integer, &Integer> for &Integer {
269    type Output = Integer;
270
271    /// Subtracts the product of one pair of [`Integer`]s from the product of another, taking all
272    /// four by reference.
273    ///
274    /// $f(x, y, z, w) = xy - zw$.
275    ///
276    /// # Worst-case complexity
277    /// $T(n) = O(n \log n \log\log n)$
278    ///
279    /// $M(n) = O(n \log n)$
280    ///
281    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
282    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
283    ///
284    /// # Examples
285    /// ```
286    /// use malachite_base::num::arithmetic::traits::MulSubMul;
287    /// use malachite_nz::integer::Integer;
288    ///
289    /// assert_eq!(
290    ///     (&Integer::from(-10)).mul_sub_mul(
291    ///         &Integer::from(3),
292    ///         &Integer::from(4),
293    ///         &Integer::from(5)
294    ///     ),
295    ///     -50
296    /// );
297    /// ```
298    #[inline]
299    fn mul_sub_mul(self, y: &Integer, z: &Integer, w: &Integer) -> Integer {
300        (self * y).sub_mul(z, w)
301    }
302}
303
304impl MulSubMulAssign<Self, Self, Self> for Integer {
305    /// Subtracts the product of one pair of [`Integer`]s from the product of another, in place,
306    /// taking all four by value.
307    ///
308    /// $x \gets xy - zw$.
309    ///
310    /// # Worst-case complexity
311    /// $T(n) = O(n \log n \log\log n)$
312    ///
313    /// $M(n) = O(n \log n)$
314    ///
315    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
316    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
317    ///
318    /// # Examples
319    /// ```
320    /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
321    /// use malachite_nz::integer::Integer;
322    ///
323    /// let mut x = Integer::from(-10);
324    /// x.mul_sub_mul_assign(Integer::from(3), Integer::from(4), Integer::from(5));
325    /// assert_eq!(x, -50);
326    /// ```
327    #[inline]
328    fn mul_sub_mul_assign(&mut self, y: Self, z: Self, w: Self) {
329        *self *= y;
330        self.sub_mul_assign(z, w);
331    }
332}
333
334impl MulSubMulAssign<Self, Self, &Self> for Integer {
335    /// Subtracts the product of one pair of [`Integer`]s from the product of another, in place,
336    /// taking $x$, $y$ and $z$ by value and $w$ by reference.
337    ///
338    /// $x \gets xy - zw$.
339    ///
340    /// # Worst-case complexity
341    /// $T(n) = O(n \log n \log\log n)$
342    ///
343    /// $M(n) = O(n \log n)$
344    ///
345    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
346    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
347    ///
348    /// # Examples
349    /// ```
350    /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
351    /// use malachite_nz::integer::Integer;
352    ///
353    /// let mut x = Integer::from(-10);
354    /// x.mul_sub_mul_assign(Integer::from(3), Integer::from(4), &Integer::from(5));
355    /// assert_eq!(x, -50);
356    /// ```
357    #[inline]
358    fn mul_sub_mul_assign(&mut self, y: Self, z: Self, w: &Self) {
359        *self *= y;
360        self.sub_mul_assign(z, w);
361    }
362}
363
364impl MulSubMulAssign<Self, &Self, Self> for Integer {
365    /// Subtracts the product of one pair of [`Integer`]s from the product of another, in place,
366    /// taking $x$, $y$ and $w$ by value and $z$ by reference.
367    ///
368    /// $x \gets xy - zw$.
369    ///
370    /// # Worst-case complexity
371    /// $T(n) = O(n \log n \log\log n)$
372    ///
373    /// $M(n) = O(n \log n)$
374    ///
375    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
376    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
377    ///
378    /// # Examples
379    /// ```
380    /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
381    /// use malachite_nz::integer::Integer;
382    ///
383    /// let mut x = Integer::from(-10);
384    /// x.mul_sub_mul_assign(Integer::from(3), &Integer::from(4), Integer::from(5));
385    /// assert_eq!(x, -50);
386    /// ```
387    #[inline]
388    fn mul_sub_mul_assign(&mut self, y: Self, z: &Self, w: Self) {
389        *self *= y;
390        self.sub_mul_assign(z, w);
391    }
392}
393
394impl MulSubMulAssign<Self, &Self, &Self> for Integer {
395    /// Subtracts the product of one pair of [`Integer`]s from the product of another, in place,
396    /// taking $x$ and $y$ by value and $z$ and $w$ by reference.
397    ///
398    /// $x \gets xy - zw$.
399    ///
400    /// # Worst-case complexity
401    /// $T(n) = O(n \log n \log\log n)$
402    ///
403    /// $M(n) = O(n \log n)$
404    ///
405    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
406    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
407    ///
408    /// # Examples
409    /// ```
410    /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
411    /// use malachite_nz::integer::Integer;
412    ///
413    /// let mut x = Integer::from(-10);
414    /// x.mul_sub_mul_assign(Integer::from(3), &Integer::from(4), &Integer::from(5));
415    /// assert_eq!(x, -50);
416    /// ```
417    #[inline]
418    fn mul_sub_mul_assign(&mut self, y: Self, z: &Self, w: &Self) {
419        *self *= y;
420        self.sub_mul_assign(z, w);
421    }
422}
423
424impl MulSubMulAssign<&Self, Self, Self> for Integer {
425    /// Subtracts the product of one pair of [`Integer`]s from the product of another, in place,
426    /// taking $x$, $z$ and $w$ by value and $y$ by reference.
427    ///
428    /// $x \gets xy - zw$.
429    ///
430    /// # Worst-case complexity
431    /// $T(n) = O(n \log n \log\log n)$
432    ///
433    /// $M(n) = O(n \log n)$
434    ///
435    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
436    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
437    ///
438    /// # Examples
439    /// ```
440    /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
441    /// use malachite_nz::integer::Integer;
442    ///
443    /// let mut x = Integer::from(-10);
444    /// x.mul_sub_mul_assign(&Integer::from(3), Integer::from(4), Integer::from(5));
445    /// assert_eq!(x, -50);
446    /// ```
447    #[inline]
448    fn mul_sub_mul_assign(&mut self, y: &Self, z: Self, w: Self) {
449        *self *= y;
450        self.sub_mul_assign(z, w);
451    }
452}
453
454impl MulSubMulAssign<&Self, Self, &Self> for Integer {
455    /// Subtracts the product of one pair of [`Integer`]s from the product of another, in place,
456    /// taking $x$ and $z$ by value and $y$ and $w$ by reference.
457    ///
458    /// $x \gets xy - zw$.
459    ///
460    /// # Worst-case complexity
461    /// $T(n) = O(n \log n \log\log n)$
462    ///
463    /// $M(n) = O(n \log n)$
464    ///
465    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
466    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
467    ///
468    /// # Examples
469    /// ```
470    /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
471    /// use malachite_nz::integer::Integer;
472    ///
473    /// let mut x = Integer::from(-10);
474    /// x.mul_sub_mul_assign(&Integer::from(3), Integer::from(4), &Integer::from(5));
475    /// assert_eq!(x, -50);
476    /// ```
477    #[inline]
478    fn mul_sub_mul_assign(&mut self, y: &Self, z: Self, w: &Self) {
479        *self *= y;
480        self.sub_mul_assign(z, w);
481    }
482}
483
484impl MulSubMulAssign<&Self, &Self, Self> for Integer {
485    /// Subtracts the product of one pair of [`Integer`]s from the product of another, in place,
486    /// taking $x$ and $w$ by value and $y$ and $z$ by reference.
487    ///
488    /// $x \gets xy - zw$.
489    ///
490    /// # Worst-case complexity
491    /// $T(n) = O(n \log n \log\log n)$
492    ///
493    /// $M(n) = O(n \log n)$
494    ///
495    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
496    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
497    ///
498    /// # Examples
499    /// ```
500    /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
501    /// use malachite_nz::integer::Integer;
502    ///
503    /// let mut x = Integer::from(-10);
504    /// x.mul_sub_mul_assign(&Integer::from(3), &Integer::from(4), Integer::from(5));
505    /// assert_eq!(x, -50);
506    /// ```
507    #[inline]
508    fn mul_sub_mul_assign(&mut self, y: &Self, z: &Self, w: Self) {
509        *self *= y;
510        self.sub_mul_assign(z, w);
511    }
512}
513
514impl MulSubMulAssign<&Self, &Self, &Self> for Integer {
515    /// Subtracts the product of one pair of [`Integer`]s from the product of another, in place,
516    /// taking $x$ by value and $y$, $z$ and $w$ by reference.
517    ///
518    /// $x \gets xy - zw$.
519    ///
520    /// # Worst-case complexity
521    /// $T(n) = O(n \log n \log\log n)$
522    ///
523    /// $M(n) = O(n \log n)$
524    ///
525    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
526    /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
527    ///
528    /// # Examples
529    /// ```
530    /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
531    /// use malachite_nz::integer::Integer;
532    ///
533    /// let mut x = Integer::from(-10);
534    /// x.mul_sub_mul_assign(&Integer::from(3), &Integer::from(4), &Integer::from(5));
535    /// assert_eq!(x, -50);
536    /// ```
537    #[inline]
538    fn mul_sub_mul_assign(&mut self, y: &Self, z: &Self, w: &Self) {
539        *self *= y;
540        self.sub_mul_assign(z, w);
541    }
542}