malachite_nz/integer/arithmetic/
add.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 crate::natural::Natural;
11use core::iter::Sum;
12use core::mem::swap;
13use core::ops::{Add, AddAssign};
14use malachite_base::num::basic::traits::Zero;
15
16impl Add<Integer> for Integer {
17    type Output = Integer;
18
19    /// Adds two [`Integer`]s, taking both by value.
20    ///
21    /// $$
22    /// f(x, y) = x + y.
23    /// $$
24    ///
25    /// # Worst-case complexity
26    /// $T(n) = O(n)$
27    ///
28    /// $M(n) = O(n)$ (only if the underlying [`Vec`] needs to reallocate)
29    ///
30    /// where $T$ is time, $M$ is additional memory, and $n$ is `min(self.significant_bits(),
31    /// other.significant_bits())`.
32    ///
33    /// # Examples
34    /// ```
35    /// use malachite_base::num::arithmetic::traits::Pow;
36    /// use malachite_base::num::basic::traits::Zero;
37    /// use malachite_nz::integer::Integer;
38    ///
39    /// assert_eq!(Integer::ZERO + Integer::from(123), 123);
40    /// assert_eq!(Integer::from(-123) + Integer::ZERO, -123);
41    /// assert_eq!(Integer::from(-123) + Integer::from(456), 333);
42    /// assert_eq!(
43    ///     -Integer::from(10u32).pow(12) + (Integer::from(10u32).pow(12) << 1),
44    ///     1000000000000u64
45    /// );
46    /// ```
47    fn add(mut self, mut other: Integer) -> Integer {
48        if self.abs.limb_count() >= other.abs.limb_count() {
49            self += other;
50            self
51        } else {
52            other += self;
53            other
54        }
55    }
56}
57
58impl Add<&Integer> for Integer {
59    type Output = Integer;
60
61    /// Adds two [`Integer`]s, taking the first by reference and the second by value.
62    ///
63    /// $$
64    /// f(x, y) = x + y.
65    /// $$
66    ///
67    /// # Worst-case complexity
68    /// $T(n) = O(n)$
69    ///
70    /// $M(n) = O(n)$
71    ///
72    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
73    /// other.significant_bits())`.
74    ///
75    /// # Examples
76    /// ```
77    /// use malachite_base::num::arithmetic::traits::Pow;
78    /// use malachite_base::num::basic::traits::Zero;
79    /// use malachite_nz::integer::Integer;
80    ///
81    /// assert_eq!(Integer::ZERO + &Integer::from(123), 123);
82    /// assert_eq!(Integer::from(-123) + &Integer::ZERO, -123);
83    /// assert_eq!(Integer::from(-123) + &Integer::from(456), 333);
84    /// assert_eq!(
85    ///     -Integer::from(10u32).pow(12) + &(Integer::from(10u32).pow(12) << 1),
86    ///     1000000000000u64
87    /// );
88    /// ```
89    #[inline]
90    fn add(mut self, other: &Integer) -> Integer {
91        self += other;
92        self
93    }
94}
95
96impl Add<Integer> for &Integer {
97    type Output = Integer;
98
99    /// Adds two [`Integer`]s, taking the first by value and the second by reference.
100    ///
101    /// $$
102    /// f(x, y) = x + y.
103    /// $$
104    ///
105    /// # Worst-case complexity
106    /// $T(n) = O(n)$
107    ///
108    /// $M(n) = O(n)$
109    ///
110    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
111    /// other.significant_bits())`.
112    ///
113    /// # Examples
114    /// ```
115    /// use malachite_base::num::arithmetic::traits::Pow;
116    /// use malachite_base::num::basic::traits::Zero;
117    /// use malachite_nz::integer::Integer;
118    ///
119    /// assert_eq!(&Integer::ZERO + Integer::from(123), 123);
120    /// assert_eq!(&Integer::from(-123) + Integer::ZERO, -123);
121    /// assert_eq!(&Integer::from(-123) + Integer::from(456), 333);
122    /// assert_eq!(
123    ///     &-Integer::from(10u32).pow(12) + (Integer::from(10u32).pow(12) << 1),
124    ///     1000000000000u64
125    /// );
126    /// ```
127    #[inline]
128    fn add(self, mut other: Integer) -> Integer {
129        other += self;
130        other
131    }
132}
133
134impl Add<&Integer> for &Integer {
135    type Output = Integer;
136
137    /// Adds two [`Integer`]s, taking both by reference.
138    ///
139    /// $$
140    /// f(x, y) = x + y.
141    /// $$
142    ///
143    /// # Worst-case complexity
144    /// $T(n) = O(n)$
145    ///
146    /// $M(n) = O(n)$
147    ///
148    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
149    /// other.significant_bits())`.
150    ///
151    /// # Examples
152    /// ```
153    /// use malachite_base::num::arithmetic::traits::Pow;
154    /// use malachite_base::num::basic::traits::Zero;
155    /// use malachite_nz::integer::Integer;
156    ///
157    /// assert_eq!(&Integer::ZERO + &Integer::from(123), 123);
158    /// assert_eq!(&Integer::from(-123) + &Integer::ZERO, -123);
159    /// assert_eq!(&Integer::from(-123) + &Integer::from(456), 333);
160    /// assert_eq!(
161    ///     &-Integer::from(10u32).pow(12) + &(Integer::from(10u32).pow(12) << 1),
162    ///     1000000000000u64
163    /// );
164    /// ```
165    fn add(self, other: &Integer) -> Integer {
166        match (self, other) {
167            (x, y) if core::ptr::eq(x, y) => x << 1,
168            (&integer_zero!(), y) => y.clone(),
169            (x, &integer_zero!()) => x.clone(),
170            // e.g. 10 + 5 or -10 + -5; sign of result is sign of self
171            (
172                &Integer {
173                    sign: sx,
174                    abs: ref ax,
175                },
176                &Integer {
177                    sign: sy,
178                    abs: ref ay,
179                },
180            ) if sx == (sy && *ay != 0) => Integer {
181                sign: sx,
182                abs: ax + ay,
183            },
184            // e.g. 10 + -5, -10 + 5, or 5 + -5; sign of result is sign of self
185            (
186                &Integer {
187                    sign: sx,
188                    abs: ref ax,
189                },
190                Integer { abs: ay, .. },
191            ) if sx && *ax == *ay || *ax > *ay => Integer {
192                sign: sx,
193                abs: ax - ay,
194            },
195            // e.g. 5 + -10, -5 + 10, or -5 + 5; sign of result is sign of other
196            (
197                Integer { abs: ax, .. },
198                &Integer {
199                    sign: sy,
200                    abs: ref ay,
201                },
202            ) => Integer {
203                sign: sy,
204                abs: ay - ax,
205            },
206        }
207    }
208}
209
210impl AddAssign<Integer> for Integer {
211    /// Adds an [`Integer`] to an [`Integer`] in place, taking the [`Integer`] on the right-hand
212    /// side by value.
213    ///
214    /// $$
215    /// x \gets x + y.
216    /// $$
217    ///
218    /// # Worst-case complexity
219    /// $T(n) = O(n)$
220    ///
221    /// $M(n) = O(n)$ (only if the underlying [`Vec`] needs to reallocate)
222    ///
223    /// where $T$ is time, $M$ is additional memory, and $n$ is `min(self.significant_bits(),
224    /// other.significant_bits())`.
225    ///
226    /// # Examples
227    /// ```
228    /// use malachite_base::num::arithmetic::traits::Pow;
229    /// use malachite_base::num::basic::traits::Zero;
230    /// use malachite_nz::integer::Integer;
231    ///
232    /// let mut x = Integer::ZERO;
233    /// x += -Integer::from(10u32).pow(12);
234    /// x += Integer::from(10u32).pow(12) * Integer::from(2u32);
235    /// x += -Integer::from(10u32).pow(12) * Integer::from(3u32);
236    /// x += Integer::from(10u32).pow(12) * Integer::from(4u32);
237    /// assert_eq!(x, 2000000000000u64);
238    /// ```
239    fn add_assign(&mut self, mut other: Integer) {
240        match (&mut *self, &other) {
241            (_, &integer_zero!()) => {}
242            (&mut integer_zero!(), _) => {
243                *self = other;
244            }
245            // e.g. 10 += 5 or -10 += -5; sign of self is unchanged
246            (
247                &mut Integer {
248                    sign: sx,
249                    abs: ref mut ax,
250                },
251                &Integer {
252                    sign: sy,
253                    abs: ref ay,
254                },
255            ) if sx == (sy && *ay != 0) => *ax += ay,
256            // e.g. 10 += -5, -10 += 5, or 5 += -5; sign of self is unchanged
257            (
258                &mut Integer {
259                    sign: sx,
260                    abs: ref mut ax,
261                },
262                Integer { abs: ay, .. },
263            ) if sx && *ax == *ay || *ax > *ay => *ax -= ay,
264            // e.g. 5 += -10, -5 += 10, or -5 += 5; sign of self is flipped
265            _ => {
266                swap(self, &mut other);
267                self.abs -= other.abs;
268            }
269        };
270    }
271}
272
273impl AddAssign<&Integer> for Integer {
274    /// Adds an [`Integer`] to an [`Integer`] in place, taking the [`Integer`] on the right-hand
275    /// side by reference.
276    ///
277    /// $$
278    /// x \gets x + y.
279    /// $$
280    ///
281    /// # Worst-case complexity
282    /// $T(n) = O(n)$
283    ///
284    /// $M(n) = O(n)$
285    ///
286    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
287    /// other.significant_bits())`.
288    ///
289    /// # Examples
290    /// ```
291    /// use malachite_base::num::arithmetic::traits::Pow;
292    /// use malachite_base::num::basic::traits::Zero;
293    /// use malachite_nz::integer::Integer;
294    ///
295    /// let mut x = Integer::ZERO;
296    /// x += &(-Integer::from(10u32).pow(12));
297    /// x += &(Integer::from(10u32).pow(12) * Integer::from(2u32));
298    /// x += &(-Integer::from(10u32).pow(12) * Integer::from(3u32));
299    /// x += &(Integer::from(10u32).pow(12) * Integer::from(4u32));
300    /// assert_eq!(x, 2000000000000u64);
301    /// ```
302    fn add_assign(&mut self, other: &Integer) {
303        match (&mut *self, other) {
304            (_, &integer_zero!()) => {}
305            (&mut integer_zero!(), _) => {
306                *self = other.clone();
307            }
308            // e.g. 10 += 5 or -10 += -5; sign of self is unchanged
309            (
310                &mut Integer {
311                    sign: sx,
312                    abs: ref mut ax,
313                },
314                &Integer {
315                    sign: sy,
316                    abs: ref ay,
317                },
318            ) if sx == (sy && *ay != 0) => *ax += ay,
319            // e.g. 10 += -5, -10 += 5, or 5 += -5; sign of self is unchanged
320            (
321                &mut Integer {
322                    sign: sx,
323                    abs: ref mut ax,
324                },
325                Integer { abs: ay, .. },
326            ) if sx && *ax == *ay || *ax > *ay => *ax -= ay,
327            // e.g. 5 += -10, -5 += 10, or -5 += 5; sign of self is flipped
328            (
329                &mut Integer {
330                    sign: ref mut sx,
331                    abs: ref mut ax,
332                },
333                &Integer {
334                    sign: sy,
335                    abs: ref ay,
336                },
337            ) => {
338                *sx = sy;
339                ax.sub_right_assign_no_panic(ay);
340            }
341        };
342    }
343}
344
345impl Sum for Integer {
346    /// Adds up all the [`Integer`]s in an iterator.
347    ///
348    /// $$
349    /// f((x_i)_ {i=0}^{n-1}) = \sum_ {i=0}^{n-1} x_i.
350    /// $$
351    ///
352    /// # Worst-case complexity
353    /// $T(n) = O(n^2)$
354    ///
355    /// $M(n) = O(n)$
356    ///
357    /// where $T$ is time, $M$ is additional memory, and $n$ is
358    /// `Integer::sum(xs.map(Integer::significant_bits))`.
359    ///
360    /// # Examples
361    /// ```
362    /// use core::iter::Sum;
363    /// use malachite_base::vecs::vec_from_str;
364    /// use malachite_nz::integer::Integer;
365    ///
366    /// assert_eq!(
367    ///     Integer::sum(
368    ///         vec_from_str::<Integer>("[2, -3, 5, 7]")
369    ///             .unwrap()
370    ///             .into_iter()
371    ///     ),
372    ///     11
373    /// );
374    /// ```
375    fn sum<I>(xs: I) -> Integer
376    where
377        I: Iterator<Item = Integer>,
378    {
379        let mut s = Integer::ZERO;
380        for x in xs {
381            s += x;
382        }
383        s
384    }
385}
386
387impl<'a> Sum<&'a Integer> for Integer {
388    /// Adds up all the [`Integer`]s in an iterator of [`Integer`] references.
389    ///
390    /// $$
391    /// f((x_i)_ {i=0}^{n-1}) = \sum_ {i=0}^{n-1} x_i.
392    /// $$
393    ///
394    /// # Worst-case complexity
395    /// $T(n) = O(n^2)$
396    ///
397    /// $M(n) = O(n)$
398    ///
399    /// where $T$ is time, $M$ is additional memory, and $n$ is
400    /// `Integer::sum(xs.map(Integer::significant_bits))`.
401    ///
402    /// # Examples
403    /// ```
404    /// use core::iter::Sum;
405    /// use malachite_base::vecs::vec_from_str;
406    /// use malachite_nz::integer::Integer;
407    ///
408    /// assert_eq!(
409    ///     Integer::sum(vec_from_str::<Integer>("[2, -3, 5, 7]").unwrap().iter()),
410    ///     11
411    /// );
412    /// ```
413    fn sum<I>(xs: I) -> Integer
414    where
415        I: Iterator<Item = &'a Integer>,
416    {
417        let mut s = Integer::ZERO;
418        for x in xs {
419            s += x;
420        }
421        s
422    }
423}