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}