malachite_nz/integer/arithmetic/mul.rs
1// Copyright © 2025 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 alloc::vec::Vec;
11use core::iter::Product;
12use core::ops::{Mul, MulAssign};
13use malachite_base::num::basic::traits::{One, Zero};
14
15impl Mul<Integer> for Integer {
16 type Output = Integer;
17
18 /// Multiplies two [`Integer`]s, taking both by value.
19 ///
20 /// $$
21 /// f(x, y) = xy.
22 /// $$
23 ///
24 /// # Worst-case complexity
25 /// $T(n) = O(n \log n \log\log n)$
26 ///
27 /// $M(n) = O(n \log n)$
28 ///
29 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
30 /// other.significant_bits())`.
31 ///
32 /// # Examples
33 /// ```
34 /// use malachite_base::num::basic::traits::{One, Zero};
35 /// use malachite_nz::integer::Integer;
36 ///
37 /// assert_eq!(Integer::ONE * Integer::from(123), 123);
38 /// assert_eq!(Integer::from(123) * Integer::ZERO, 0);
39 /// assert_eq!(Integer::from(123) * Integer::from(-456), -56088);
40 /// assert_eq!(
41 /// (Integer::from(-123456789000i64) * Integer::from(-987654321000i64)).to_string(),
42 /// "121932631112635269000000"
43 /// );
44 /// ```
45 fn mul(mut self, other: Integer) -> Integer {
46 self *= other;
47 self
48 }
49}
50
51impl Mul<&Integer> for Integer {
52 type Output = Integer;
53
54 /// Multiplies two [`Integer`]s, taking the first by value and the second by reference.
55 ///
56 /// $$
57 /// f(x, y) = xy.
58 /// $$
59 ///
60 /// # Worst-case complexity
61 /// $T(n) = O(n \log n \log\log n)$
62 ///
63 /// $M(n) = O(n \log n)$
64 ///
65 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
66 /// other.significant_bits())`.
67 ///
68 /// # Examples
69 /// ```
70 /// use malachite_base::num::basic::traits::{One, Zero};
71 /// use malachite_nz::integer::Integer;
72 ///
73 /// assert_eq!(Integer::ONE * &Integer::from(123), 123);
74 /// assert_eq!(Integer::from(123) * &Integer::ZERO, 0);
75 /// assert_eq!(Integer::from(123) * &Integer::from(-456), -56088);
76 /// assert_eq!(
77 /// (Integer::from(-123456789000i64) * &Integer::from(-987654321000i64)).to_string(),
78 /// "121932631112635269000000"
79 /// );
80 /// ```
81 fn mul(mut self, other: &Integer) -> Integer {
82 self *= other;
83 self
84 }
85}
86
87impl Mul<Integer> for &Integer {
88 type Output = Integer;
89
90 /// Multiplies two [`Integer`]s, taking the first by reference and the second by value.
91 ///
92 /// $$
93 /// f(x, y) = xy.
94 /// $$
95 ///
96 /// # Worst-case complexity
97 /// $T(n) = O(n \log n \log\log n)$
98 ///
99 /// $M(n) = O(n \log n)$
100 ///
101 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
102 /// other.significant_bits())`.
103 ///
104 /// # Examples
105 /// ```
106 /// use malachite_base::num::basic::traits::{One, Zero};
107 /// use malachite_nz::integer::Integer;
108 ///
109 /// assert_eq!(&Integer::ONE * Integer::from(123), 123);
110 /// assert_eq!(&Integer::from(123) * Integer::ZERO, 0);
111 /// assert_eq!(&Integer::from(123) * Integer::from(-456), -56088);
112 /// assert_eq!(
113 /// (&Integer::from(-123456789000i64) * Integer::from(-987654321000i64)).to_string(),
114 /// "121932631112635269000000"
115 /// );
116 /// ```
117 fn mul(self, mut other: Integer) -> Integer {
118 other *= self;
119 other
120 }
121}
122
123impl Mul<&Integer> for &Integer {
124 type Output = Integer;
125
126 /// Multiplies two [`Integer`]s, taking both by reference.
127 ///
128 /// $$
129 /// f(x, y) = xy.
130 /// $$
131 ///
132 /// # Worst-case complexity
133 /// $T(n) = O(n \log n \log\log n)$
134 ///
135 /// $M(n) = O(n \log n)$
136 ///
137 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
138 /// other.significant_bits())`.
139 ///
140 /// # Examples
141 /// ```
142 /// use malachite_base::num::basic::traits::{One, Zero};
143 /// use malachite_nz::integer::Integer;
144 ///
145 /// assert_eq!(&Integer::ONE * &Integer::from(123), 123);
146 /// assert_eq!(&Integer::from(123) * &Integer::ZERO, 0);
147 /// assert_eq!(&Integer::from(123) * &Integer::from(-456), -56088);
148 /// assert_eq!(
149 /// (&Integer::from(-123456789000i64) * &Integer::from(-987654321000i64)).to_string(),
150 /// "121932631112635269000000"
151 /// );
152 /// ```
153 fn mul(self, other: &Integer) -> Integer {
154 let product_abs = &self.abs * &other.abs;
155 Integer {
156 sign: self.sign == other.sign || product_abs == 0,
157 abs: product_abs,
158 }
159 }
160}
161
162impl MulAssign<Integer> for Integer {
163 /// Multiplies an [`Integer`] by an [`Integer`] in place, taking the [`Integer`] on the
164 /// right-hand side by value.
165 ///
166 /// $$
167 /// x \gets = xy.
168 /// $$
169 ///
170 /// # Worst-case complexity
171 /// $T(n) = O(n \log n \log\log n)$
172 ///
173 /// $M(n) = O(n \log n)$
174 ///
175 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
176 /// other.significant_bits())`.
177 ///
178 /// # Examples
179 /// ```
180 /// use malachite_base::num::basic::traits::NegativeOne;
181 /// use malachite_nz::integer::Integer;
182 ///
183 /// let mut x = Integer::NEGATIVE_ONE;
184 /// x *= Integer::from(1000);
185 /// x *= Integer::from(2000);
186 /// x *= Integer::from(3000);
187 /// x *= Integer::from(4000);
188 /// assert_eq!(x, -24000000000000i64);
189 /// ```
190 fn mul_assign(&mut self, other: Integer) {
191 self.abs *= other.abs;
192 self.sign = self.sign == other.sign || self.abs == 0;
193 }
194}
195
196impl MulAssign<&Integer> for Integer {
197 /// Multiplies an [`Integer`] by an [`Integer`] in place, taking the [`Integer`] on the
198 /// right-hand side by reference.
199 ///
200 /// $$
201 /// x \gets = xy.
202 /// $$
203 ///
204 /// # Worst-case complexity
205 /// $T(n) = O(n \log n \log\log n)$
206 ///
207 /// $M(n) = O(n \log n)$
208 ///
209 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
210 /// other.significant_bits())`.
211 ///
212 /// # Examples
213 /// ```
214 /// use malachite_base::num::basic::traits::NegativeOne;
215 /// use malachite_nz::integer::Integer;
216 ///
217 /// let mut x = Integer::NEGATIVE_ONE;
218 /// x *= &Integer::from(1000);
219 /// x *= &Integer::from(2000);
220 /// x *= &Integer::from(3000);
221 /// x *= &Integer::from(4000);
222 /// assert_eq!(x, -24000000000000i64);
223 /// ```
224 fn mul_assign(&mut self, other: &Integer) {
225 self.abs *= &other.abs;
226 self.sign = self.sign == other.sign || self.abs == 0;
227 }
228}
229
230impl Product for Integer {
231 /// Multiplies together all the [`Integer`]s in an iterator.
232 ///
233 /// $$
234 /// f((x_i)_ {i=0}^{n-1}) = \prod_ {i=0}^{n-1} x_i.
235 /// $$
236 ///
237 /// # Worst-case complexity
238 /// $T(n) = O(n (\log n)^2 \log\log n)$
239 ///
240 /// $M(n) = O(n \log n)$
241 ///
242 /// where $T$ is time, $M$ is additional memory, and $n$ is
243 /// `Integer::sum(xs.map(Integer::significant_bits))`.
244 ///
245 /// # Examples
246 /// ```
247 /// use core::iter::Product;
248 /// use malachite_base::vecs::vec_from_str;
249 /// use malachite_nz::integer::Integer;
250 ///
251 /// assert_eq!(
252 /// Integer::product(
253 /// vec_from_str::<Integer>("[2, -3, 5, 7]")
254 /// .unwrap()
255 /// .into_iter()
256 /// ),
257 /// -210
258 /// );
259 /// ```
260 fn product<I>(xs: I) -> Integer
261 where
262 I: Iterator<Item = Integer>,
263 {
264 let mut stack = Vec::new();
265 for (i, x) in xs.enumerate().map(|(i, x)| (i + 1, x)) {
266 if x == 0 {
267 return Integer::ZERO;
268 }
269 let mut p = x;
270 for _ in 0..i.trailing_zeros() {
271 p *= stack.pop().unwrap();
272 }
273 stack.push(p);
274 }
275 let mut p = Integer::ONE;
276 for x in stack.into_iter().rev() {
277 p *= x;
278 }
279 p
280 }
281}
282
283impl<'a> Product<&'a Integer> for Integer {
284 /// Multiplies together all the [`Integer`]s in an iterator of [`Integer`] references.
285 ///
286 /// $$
287 /// f((x_i)_ {i=0}^{n-1}) = \prod_ {i=0}^{n-1} x_i.
288 /// $$
289 ///
290 /// # Worst-case complexity
291 /// $T(n) = O(n (\log n)^2 \log\log n)$
292 ///
293 /// $M(n) = O(n \log n)$
294 ///
295 /// where $T$ is time, $M$ is additional memory, and $n$ is
296 /// `Integer::sum(xs.map(Integer::significant_bits))`.
297 ///
298 /// # Examples
299 /// ```
300 /// use core::iter::Product;
301 /// use malachite_base::vecs::vec_from_str;
302 /// use malachite_nz::integer::Integer;
303 ///
304 /// assert_eq!(
305 /// Integer::product(vec_from_str::<Integer>("[2, -3, 5, 7]").unwrap().iter()),
306 /// -210
307 /// );
308 /// ```
309 fn product<I>(xs: I) -> Integer
310 where
311 I: Iterator<Item = &'a Integer>,
312 {
313 let mut stack = Vec::new();
314 for (i, x) in xs.enumerate().map(|(i, x)| (i + 1, x)) {
315 if *x == 0 {
316 return Integer::ZERO;
317 }
318 let mut p = x.clone();
319 for _ in 0..i.trailing_zeros() {
320 p *= stack.pop().unwrap();
321 }
322 stack.push(p);
323 }
324 let mut p = Integer::ONE;
325 for x in stack.into_iter().rev() {
326 p *= x;
327 }
328 p
329 }
330}