Skip to main content

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}