Skip to main content

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