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}