malachite_nz/integer/arithmetic/average.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::cmp::Ordering;
11use malachite_base::num::arithmetic::traits::{
12 Average, AverageAssign, AverageRound, AverageRoundAssign, ShrRound, ShrRoundAssign,
13};
14use malachite_base::rounding_modes::RoundingMode::{self, Nearest};
15
16impl Average<Self> for Integer {
17 type Output = Self;
18
19 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking both by value and
20 /// rounding to the nearest integer. Two-way ties are broken by rounding to the even integer.
21 ///
22 /// $$
23 /// f(x, y) = \begin{cases}
24 /// a & \text{if} \\quad a \in \Z, \\\\
25 /// \lfloor a \rfloor & \text{if} \\quad a \notin \Z
26 /// \\ \text{and} \\ \lfloor a \rfloor \\ \text{is even}, \\\\
27 /// \lceil a \rceil & \text{if} \\quad a \notin \Z
28 /// \\ \text{and} \\ \lfloor a \rfloor \\ \text{is odd,}
29 /// \end{cases}
30 /// $$
31 ///
32 /// where $a = \frac{x + y}{2}$.
33 ///
34 /// # Worst-case complexity
35 /// $T(n) = O(n)$
36 ///
37 /// $M(n) = O(n)$
38 ///
39 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
40 /// other.significant_bits())`.
41 ///
42 /// # Examples
43 /// ```
44 /// use malachite_base::num::arithmetic::traits::Average;
45 /// use malachite_nz::integer::Integer;
46 ///
47 /// assert_eq!(Integer::from(4).average(Integer::from(6)), 5);
48 /// assert_eq!(Integer::from(-4).average(Integer::from(-5)), -4);
49 /// assert_eq!(Integer::from(-5).average(Integer::from(-6)), -6);
50 /// ```
51 #[inline]
52 fn average(self, other: Self) -> Self {
53 (self + other).shr_round(1u64, Nearest).0
54 }
55}
56
57impl Average<&Self> for Integer {
58 type Output = Self;
59
60 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking the first by value and
61 /// the second by reference and rounding to the nearest integer. Two-way ties are broken by
62 /// rounding to the even integer.
63 ///
64 /// $$
65 /// f(x, y) = \begin{cases}
66 /// a & \text{if} \\quad a \in \Z, \\\\
67 /// \lfloor a \rfloor & \text{if} \\quad a \notin \Z
68 /// \\ \text{and} \\ \lfloor a \rfloor \\ \text{is even}, \\\\
69 /// \lceil a \rceil & \text{if} \\quad a \notin \Z
70 /// \\ \text{and} \\ \lfloor a \rfloor \\ \text{is odd,}
71 /// \end{cases}
72 /// $$
73 ///
74 /// where $a = \frac{x + y}{2}$.
75 ///
76 /// # Worst-case complexity
77 /// $T(n) = O(n)$
78 ///
79 /// $M(n) = O(n)$
80 ///
81 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
82 /// other.significant_bits())`.
83 ///
84 /// # Examples
85 /// ```
86 /// use malachite_base::num::arithmetic::traits::Average;
87 /// use malachite_nz::integer::Integer;
88 ///
89 /// assert_eq!(Integer::from(4).average(&Integer::from(6)), 5);
90 /// assert_eq!(Integer::from(-4).average(&Integer::from(-5)), -4);
91 /// assert_eq!(Integer::from(-5).average(&Integer::from(-6)), -6);
92 /// ```
93 #[inline]
94 fn average(self, other: &Self) -> Self {
95 (self + other).shr_round(1u64, Nearest).0
96 }
97}
98
99impl Average<Integer> for &Integer {
100 type Output = Integer;
101
102 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking the first by reference
103 /// and the second by value and rounding to the nearest integer. Two-way ties are broken by
104 /// rounding to the even integer.
105 ///
106 /// $$
107 /// f(x, y) = \begin{cases}
108 /// a & \text{if} \\quad a \in \Z, \\\\
109 /// \lfloor a \rfloor & \text{if} \\quad a \notin \Z
110 /// \\ \text{and} \\ \lfloor a \rfloor \\ \text{is even}, \\\\
111 /// \lceil a \rceil & \text{if} \\quad a \notin \Z
112 /// \\ \text{and} \\ \lfloor a \rfloor \\ \text{is odd,}
113 /// \end{cases}
114 /// $$
115 ///
116 /// where $a = \frac{x + y}{2}$.
117 ///
118 /// # Worst-case complexity
119 /// $T(n) = O(n)$
120 ///
121 /// $M(n) = O(n)$
122 ///
123 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
124 /// other.significant_bits())`.
125 ///
126 /// # Examples
127 /// ```
128 /// use malachite_base::num::arithmetic::traits::Average;
129 /// use malachite_nz::integer::Integer;
130 ///
131 /// assert_eq!((&Integer::from(4)).average(Integer::from(6)), 5);
132 /// assert_eq!((&Integer::from(-4)).average(Integer::from(-5)), -4);
133 /// assert_eq!((&Integer::from(-5)).average(Integer::from(-6)), -6);
134 /// ```
135 #[inline]
136 fn average(self, other: Integer) -> Integer {
137 (self + other).shr_round(1u64, Nearest).0
138 }
139}
140
141impl Average<&Integer> for &Integer {
142 type Output = Integer;
143
144 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking both by reference and
145 /// rounding to the nearest integer. Two-way ties are broken by rounding to the even integer.
146 ///
147 /// $$
148 /// f(x, y) = \begin{cases}
149 /// a & \text{if} \\quad a \in \Z, \\\\
150 /// \lfloor a \rfloor & \text{if} \\quad a \notin \Z
151 /// \\ \text{and} \\ \lfloor a \rfloor \\ \text{is even}, \\\\
152 /// \lceil a \rceil & \text{if} \\quad a \notin \Z
153 /// \\ \text{and} \\ \lfloor a \rfloor \\ \text{is odd,}
154 /// \end{cases}
155 /// $$
156 ///
157 /// where $a = \frac{x + y}{2}$.
158 ///
159 /// # Worst-case complexity
160 /// $T(n) = O(n)$
161 ///
162 /// $M(n) = O(n)$
163 ///
164 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
165 /// other.significant_bits())`.
166 ///
167 /// # Examples
168 /// ```
169 /// use malachite_base::num::arithmetic::traits::Average;
170 /// use malachite_nz::integer::Integer;
171 ///
172 /// assert_eq!((&Integer::from(4)).average(&Integer::from(6)), 5);
173 /// assert_eq!((&Integer::from(-4)).average(&Integer::from(-5)), -4);
174 /// assert_eq!((&Integer::from(-5)).average(&Integer::from(-6)), -6);
175 /// ```
176 #[inline]
177 fn average(self, other: &Integer) -> Integer {
178 (self + other).shr_round(1u64, Nearest).0
179 }
180}
181
182impl AverageAssign<Self> for Integer {
183 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking the [`Integer`] on the
184 /// right-hand side by value, rounding to the nearest integer, and replacing the first
185 /// [`Integer`] with it. Two-way ties are broken by rounding to the even integer.
186 ///
187 /// # Worst-case complexity
188 /// $T(n) = O(n)$
189 ///
190 /// $M(n) = O(n)$
191 ///
192 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
193 /// other.significant_bits())`.
194 ///
195 /// # Examples
196 /// ```
197 /// use malachite_base::num::arithmetic::traits::AverageAssign;
198 /// use malachite_nz::integer::Integer;
199 ///
200 /// let mut x = Integer::from(-5);
201 /// x.average_assign(Integer::from(-6));
202 /// assert_eq!(x, -6);
203 /// ```
204 #[inline]
205 fn average_assign(&mut self, other: Self) {
206 *self += other;
207 self.shr_round_assign(1u64, Nearest);
208 }
209}
210
211impl AverageAssign<&Self> for Integer {
212 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking the [`Integer`] on the
213 /// right-hand side by reference, rounding to the nearest integer, and replacing the first
214 /// [`Integer`] with it. Two-way ties are broken by rounding to the even integer.
215 ///
216 /// # Worst-case complexity
217 /// $T(n) = O(n)$
218 ///
219 /// $M(n) = O(n)$
220 ///
221 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
222 /// other.significant_bits())`.
223 ///
224 /// # Examples
225 /// ```
226 /// use malachite_base::num::arithmetic::traits::AverageAssign;
227 /// use malachite_nz::integer::Integer;
228 ///
229 /// let mut x = Integer::from(-5);
230 /// x.average_assign(&Integer::from(-6));
231 /// assert_eq!(x, -6);
232 /// ```
233 #[inline]
234 fn average_assign(&mut self, other: &Self) {
235 *self += other;
236 self.shr_round_assign(1u64, Nearest);
237 }
238}
239
240impl AverageRound<Self> for Integer {
241 type Output = Self;
242
243 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking both by value and
244 /// rounding according to a specified rounding mode. An [`Ordering`] is also returned,
245 /// indicating whether the returned value is less than, equal to, or greater than the exact
246 /// value.
247 ///
248 /// Let $a = \frac{x + y}{2}$. The rounding of an inexact average follows the [`AverageRound`]
249 /// documentation in `malachite-base`, and the returned [`Ordering`] indicates whether the
250 /// result is less than, equal to, or greater than $a$.
251 ///
252 /// # Worst-case complexity
253 /// $T(n) = O(n)$
254 ///
255 /// $M(n) = O(n)$
256 ///
257 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
258 /// other.significant_bits())`.
259 ///
260 /// # Panics
261 /// Panics if `rm` is `Exact` but the average of `self` and `other` is not an integer.
262 ///
263 /// # Examples
264 /// ```
265 /// use core::cmp::Ordering::*;
266 /// use malachite_base::num::arithmetic::traits::AverageRound;
267 /// use malachite_base::rounding_modes::RoundingMode::*;
268 /// use malachite_nz::integer::Integer;
269 ///
270 /// assert_eq!(
271 /// Integer::from(-4).average_round(Integer::from(-7), Floor),
272 /// (Integer::from(-6), Less)
273 /// );
274 /// assert_eq!(
275 /// Integer::from(-4).average_round(Integer::from(-7), Ceiling),
276 /// (Integer::from(-5), Greater)
277 /// );
278 /// assert_eq!(
279 /// Integer::from(-4).average_round(Integer::from(-7), Down),
280 /// (Integer::from(-5), Greater)
281 /// );
282 /// assert_eq!(
283 /// Integer::from(-4).average_round(Integer::from(-6), Exact),
284 /// (Integer::from(-5), Equal)
285 /// );
286 /// ```
287 #[inline]
288 fn average_round(self, other: Self, rm: RoundingMode) -> (Self, Ordering) {
289 (self + other).shr_round(1u64, rm)
290 }
291}
292
293impl AverageRound<&Self> for Integer {
294 type Output = Self;
295
296 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking the first by value and
297 /// the second by reference and rounding according to a specified rounding mode. An [`Ordering`]
298 /// is also returned, indicating whether the returned value is less than, equal to, or greater
299 /// than the exact value.
300 ///
301 /// Let $a = \frac{x + y}{2}$. The rounding of an inexact average follows the [`AverageRound`]
302 /// documentation in `malachite-base`, and the returned [`Ordering`] indicates whether the
303 /// result is less than, equal to, or greater than $a$.
304 ///
305 /// # Worst-case complexity
306 /// $T(n) = O(n)$
307 ///
308 /// $M(n) = O(n)$
309 ///
310 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
311 /// other.significant_bits())`.
312 ///
313 /// # Panics
314 /// Panics if `rm` is `Exact` but the average of `self` and `other` is not an integer.
315 ///
316 /// # Examples
317 /// ```
318 /// use core::cmp::Ordering::*;
319 /// use malachite_base::num::arithmetic::traits::AverageRound;
320 /// use malachite_base::rounding_modes::RoundingMode::*;
321 /// use malachite_nz::integer::Integer;
322 ///
323 /// assert_eq!(
324 /// Integer::from(-4).average_round(&Integer::from(-7), Floor),
325 /// (Integer::from(-6), Less)
326 /// );
327 /// assert_eq!(
328 /// Integer::from(-4).average_round(&Integer::from(-7), Ceiling),
329 /// (Integer::from(-5), Greater)
330 /// );
331 /// assert_eq!(
332 /// Integer::from(-4).average_round(&Integer::from(-7), Down),
333 /// (Integer::from(-5), Greater)
334 /// );
335 /// assert_eq!(
336 /// Integer::from(-4).average_round(&Integer::from(-6), Exact),
337 /// (Integer::from(-5), Equal)
338 /// );
339 /// ```
340 #[inline]
341 fn average_round(self, other: &Self, rm: RoundingMode) -> (Self, Ordering) {
342 (self + other).shr_round(1u64, rm)
343 }
344}
345
346impl AverageRound<Integer> for &Integer {
347 type Output = Integer;
348
349 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking the first by reference
350 /// and the second by value and rounding according to a specified rounding mode. An [`Ordering`]
351 /// is also returned, indicating whether the returned value is less than, equal to, or greater
352 /// than the exact value.
353 ///
354 /// Let $a = \frac{x + y}{2}$. The rounding of an inexact average follows the [`AverageRound`]
355 /// documentation in `malachite-base`, and the returned [`Ordering`] indicates whether the
356 /// result is less than, equal to, or greater than $a$.
357 ///
358 /// # Worst-case complexity
359 /// $T(n) = O(n)$
360 ///
361 /// $M(n) = O(n)$
362 ///
363 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
364 /// other.significant_bits())`.
365 ///
366 /// # Panics
367 /// Panics if `rm` is `Exact` but the average of `self` and `other` is not an integer.
368 ///
369 /// # Examples
370 /// ```
371 /// use core::cmp::Ordering::*;
372 /// use malachite_base::num::arithmetic::traits::AverageRound;
373 /// use malachite_base::rounding_modes::RoundingMode::*;
374 /// use malachite_nz::integer::Integer;
375 ///
376 /// assert_eq!(
377 /// (&Integer::from(-4)).average_round(Integer::from(-7), Floor),
378 /// (Integer::from(-6), Less)
379 /// );
380 /// assert_eq!(
381 /// (&Integer::from(-4)).average_round(Integer::from(-7), Ceiling),
382 /// (Integer::from(-5), Greater)
383 /// );
384 /// assert_eq!(
385 /// (&Integer::from(-4)).average_round(Integer::from(-7), Down),
386 /// (Integer::from(-5), Greater)
387 /// );
388 /// assert_eq!(
389 /// (&Integer::from(-4)).average_round(Integer::from(-6), Exact),
390 /// (Integer::from(-5), Equal)
391 /// );
392 /// ```
393 #[inline]
394 fn average_round(self, other: Integer, rm: RoundingMode) -> (Integer, Ordering) {
395 (self + other).shr_round(1u64, rm)
396 }
397}
398
399impl AverageRound<&Integer> for &Integer {
400 type Output = Integer;
401
402 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking both by reference and
403 /// rounding according to a specified rounding mode. An [`Ordering`] is also returned,
404 /// indicating whether the returned value is less than, equal to, or greater than the exact
405 /// value.
406 ///
407 /// Let $a = \frac{x + y}{2}$. The rounding of an inexact average follows the [`AverageRound`]
408 /// documentation in `malachite-base`, and the returned [`Ordering`] indicates whether the
409 /// result is less than, equal to, or greater than $a$.
410 ///
411 /// # Worst-case complexity
412 /// $T(n) = O(n)$
413 ///
414 /// $M(n) = O(n)$
415 ///
416 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
417 /// other.significant_bits())`.
418 ///
419 /// # Panics
420 /// Panics if `rm` is `Exact` but the average of `self` and `other` is not an integer.
421 ///
422 /// # Examples
423 /// ```
424 /// use core::cmp::Ordering::*;
425 /// use malachite_base::num::arithmetic::traits::AverageRound;
426 /// use malachite_base::rounding_modes::RoundingMode::*;
427 /// use malachite_nz::integer::Integer;
428 ///
429 /// assert_eq!(
430 /// (&Integer::from(-4)).average_round(&Integer::from(-7), Floor),
431 /// (Integer::from(-6), Less)
432 /// );
433 /// assert_eq!(
434 /// (&Integer::from(-4)).average_round(&Integer::from(-7), Ceiling),
435 /// (Integer::from(-5), Greater)
436 /// );
437 /// assert_eq!(
438 /// (&Integer::from(-4)).average_round(&Integer::from(-7), Down),
439 /// (Integer::from(-5), Greater)
440 /// );
441 /// assert_eq!(
442 /// (&Integer::from(-4)).average_round(&Integer::from(-6), Exact),
443 /// (Integer::from(-5), Equal)
444 /// );
445 /// ```
446 #[inline]
447 fn average_round(self, other: &Integer, rm: RoundingMode) -> (Integer, Ordering) {
448 (self + other).shr_round(1u64, rm)
449 }
450}
451
452impl AverageRoundAssign<Self> for Integer {
453 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking the [`Integer`] on the
454 /// right-hand side by value, rounding according to a specified rounding mode, and replacing the
455 /// first [`Integer`] with it. An [`Ordering`] is returned, indicating whether the assigned
456 /// value is less than, equal to, or greater than the exact value.
457 ///
458 /// Let $a = \frac{x + y}{2}$. The rounding of an inexact average follows the [`AverageRound`]
459 /// documentation in `malachite-base`, and the returned [`Ordering`] indicates whether the
460 /// result is less than, equal to, or greater than $a$.
461 ///
462 /// # Worst-case complexity
463 /// $T(n) = O(n)$
464 ///
465 /// $M(n) = O(n)$
466 ///
467 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
468 /// other.significant_bits())`.
469 ///
470 /// # Panics
471 /// Panics if `rm` is `Exact` but the average of `self` and `other` is not an integer.
472 ///
473 /// # Examples
474 /// ```
475 /// use core::cmp::Ordering::*;
476 /// use malachite_base::num::arithmetic::traits::AverageRoundAssign;
477 /// use malachite_base::rounding_modes::RoundingMode::*;
478 /// use malachite_nz::integer::Integer;
479 ///
480 /// let mut x = Integer::from(-4);
481 /// assert_eq!(x.average_round_assign(Integer::from(-7), Floor), Less);
482 /// assert_eq!(x, -6);
483 /// ```
484 #[inline]
485 fn average_round_assign(&mut self, other: Self, rm: RoundingMode) -> Ordering {
486 *self += other;
487 self.shr_round_assign(1u64, rm)
488 }
489}
490
491impl AverageRoundAssign<&Self> for Integer {
492 /// Computes the average (arithmetic mean) of two [`Integer`]s, taking the [`Integer`] on the
493 /// right-hand side by reference, rounding according to a specified rounding mode, and replacing
494 /// the first [`Integer`] with it. An [`Ordering`] is returned, indicating whether the assigned
495 /// value is less than, equal to, or greater than the exact value.
496 ///
497 /// Let $a = \frac{x + y}{2}$. The rounding of an inexact average follows the [`AverageRound`]
498 /// documentation in `malachite-base`, and the returned [`Ordering`] indicates whether the
499 /// result is less than, equal to, or greater than $a$.
500 ///
501 /// # Worst-case complexity
502 /// $T(n) = O(n)$
503 ///
504 /// $M(n) = O(n)$
505 ///
506 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
507 /// other.significant_bits())`.
508 ///
509 /// # Panics
510 /// Panics if `rm` is `Exact` but the average of `self` and `other` is not an integer.
511 ///
512 /// # Examples
513 /// ```
514 /// use core::cmp::Ordering::*;
515 /// use malachite_base::num::arithmetic::traits::AverageRoundAssign;
516 /// use malachite_base::rounding_modes::RoundingMode::*;
517 /// use malachite_nz::integer::Integer;
518 ///
519 /// let mut x = Integer::from(-4);
520 /// assert_eq!(x.average_round_assign(&Integer::from(-7), Floor), Less);
521 /// assert_eq!(x, -6);
522 /// ```
523 #[inline]
524 fn average_round_assign(&mut self, other: &Self, rm: RoundingMode) -> Ordering {
525 *self += other;
526 self.shr_round_assign(1u64, rm)
527 }
528}