malachite_float/float/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::Float;
10use crate::float::basic::extended::ExtendedFloat;
11use core::cmp::Ordering::{self, *};
12use core::cmp::max;
13use malachite_base::num::arithmetic::traits::{Average, AverageAssign};
14use malachite_base::num::basic::traits::{NegativeZero, Zero};
15use malachite_base::num::conversion::traits::ExactFrom;
16use malachite_base::num::logic::traits::SignificantBits;
17use malachite_base::rounding_modes::RoundingMode::{self, Floor, Nearest};
18
19// Computes $(x+y)/2$, rounded to the given precision with the given rounding mode. Exactly one
20// rounding is performed, so the result is the correctly-rounded average; neither the intermediate
21// sum nor the halving can overflow or underflow when the true average is in range.
22fn average_prec_round_helper(x: Float, y: Float, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
23 assert_ne!(prec, 0);
24 let (ex, ey) = match (x.get_exponent(), y.get_exponent()) {
25 (Some(ex), Some(ey)) => (ex, ey),
26 // At least one input is NaN, an infinity, or a zero. Halving leaves each of those
27 // unchanged, so the sum is already the average, except when a zero is paired with a finite
28 // nonzero value.
29 _ => {
30 return if !x.is_finite() || !y.is_finite() || (x == 0u32 && y == 0u32) {
31 x.add_prec_round(y, prec, rm)
32 } else if x == 0u32 {
33 y.shl_prec_round(-1i64, prec, rm)
34 } else {
35 x.shl_prec_round(-1i64, prec, rm)
36 };
37 }
38 };
39 if ex > Float::MIN_EXPONENT && ey > Float::MIN_EXPONENT {
40 // Neither input is in the lowest binade, so halving each is exact. Since $|x/2+y/2| \leq
41 // \max(|x|,|y|)$, the sum cannot overflow except when the true average itself rounds out of
42 // range, and the addition is the only rounding.
43 (x >> 1u64).add_prec_round(y >> 1u64, prec, rm)
44 } else {
45 // An input is in the lowest binade, where halving would underflow.
46 let (big, small, e_big, e_small) = if ex >= ey {
47 (x, y, ex, ey)
48 } else {
49 (y, x, ey, ex)
50 };
51 let gap = u64::exact_from(i64::from(e_big) - i64::from(e_small));
52 let p = max(big.get_prec().unwrap(), small.get_prec().unwrap());
53 if gap > max(prec, p) + 2 {
54 // `small` lies below the last bit of both `big / 2` and the target grid, so it acts as
55 // a pure sticky bit: adding it whole rounds exactly as adding its half would. `big` is
56 // not in the lowest binade, since `gap` is positive, so halving it is exact.
57 (big >> 1u64).add_prec_round(small, prec, rm)
58 } else {
59 // The exact sum spans few enough bits to be affordable. Rebasing both exponents keeps
60 // the arithmetic inside `ExtendedFloat` small, and there the halving is a free
61 // adjustment of the extended exponent, so the final conversion is the only rounding.
62 let w = gap + p + 1;
63 let mut a = ExtendedFloat::from(big);
64 let mut b = ExtendedFloat::from(small);
65 let base = b.exp;
66 a.exp -= base;
67 b.exp -= base;
68 let s = a.add_prec_ref_ref(&b, w).0;
69 if s.x == 0u32 {
70 // The inputs cancel exactly. `Rational` has no signed zero, so the sign follows the
71 // rule the addition uses: an exactly zero sum is negative only when rounding toward
72 // negative infinity.
73 return (
74 if rm == Floor {
75 Float::NEGATIVE_ZERO
76 } else {
77 Float::ZERO
78 },
79 Equal,
80 );
81 }
82 // Round to the target precision while the exponent is still small, which is equivalent
83 // to rounding afterward because rounding to a precision is scale- invariant, and keeps
84 // the intermediate rational small. Only then is the rebasing undone, together with the
85 // halving; the conversion back applies that shift and handles a result that falls
86 // outside `Float`'s exponent range, composing the two orderings.
87 let (mut t, o) = ExtendedFloat::from_extended_float_prec_round_ref(&s, prec, rm);
88 t.exp += base - 1;
89 t.into_float_helper(prec, rm, o)
90 }
91 }
92}
93
94impl Float {
95 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result to the
96 /// specified precision and with the specified rounding mode, and taking both [`Float`]s by
97 /// value. An [`Ordering`] is also returned, indicating whether the returned value is less than,
98 /// equal to, or greater than the exact average.
99 ///
100 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
101 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
102 /// is itself in range.
103 ///
104 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
105 /// other than the opposite infinity is that infinity, and the average of the two opposite
106 /// infinities is `NaN`.
107 ///
108 /// $$
109 /// f(x,y,p,m) = \frac{x+y}{2},
110 /// $$
111 ///
112 /// rounded to $p$ bits in the direction specified by $m$.
113 ///
114 /// If you know you'll be using `Nearest`, consider using [`Float::average_prec`] instead. If
115 /// you know that your target precision is the maximum of the precisions of the inputs, consider
116 /// using [`Float::average_round`] instead.
117 ///
118 /// # Worst-case complexity
119 /// $T(n) = O(n \log n \log\log n)$
120 ///
121 /// $M(n) = O(n)$
122 ///
123 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
124 /// other.significant_bits())`.
125 ///
126 /// # Panics
127 /// Panics if `prec` is zero, or if `rm` is `Exact` but the average is not exactly representable
128 /// with the specified precision.
129 ///
130 /// # Examples
131 /// See [here](super::average#average_prec_round).
132 #[inline]
133 pub fn average_prec_round(self, other: Self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
134 average_prec_round_helper(self, other, prec, rm)
135 }
136
137 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result to the
138 /// specified precision and with the specified rounding mode, and taking the first [`Float`] by
139 /// value and the second by reference. An [`Ordering`] is also returned, indicating whether the
140 /// returned value is less than, equal to, or greater than the exact average.
141 ///
142 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
143 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
144 /// is itself in range.
145 ///
146 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
147 /// other than the opposite infinity is that infinity, and the average of the two opposite
148 /// infinities is `NaN`.
149 ///
150 /// $$
151 /// f(x,y,p,m) = \frac{x+y}{2},
152 /// $$
153 ///
154 /// rounded to $p$ bits in the direction specified by $m$.
155 ///
156 /// If you know you'll be using `Nearest`, consider using [`Float::average_prec_val_ref`]
157 /// instead. If you know that your target precision is the maximum of the precisions of the
158 /// inputs, consider using [`Float::average_round_val_ref`] instead.
159 ///
160 /// # Worst-case complexity
161 /// $T(n) = O(n \log n \log\log n)$
162 ///
163 /// $M(n) = O(n)$
164 ///
165 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
166 /// other.significant_bits())`.
167 ///
168 /// # Panics
169 /// Panics if `prec` is zero, or if `rm` is `Exact` but the average is not exactly representable
170 /// with the specified precision.
171 ///
172 /// # Examples
173 /// See [here](super::average#average_prec_round).
174 #[inline]
175 pub fn average_prec_round_val_ref(
176 self,
177 other: &Self,
178 prec: u64,
179 rm: RoundingMode,
180 ) -> (Self, Ordering) {
181 average_prec_round_helper(self, other.clone(), prec, rm)
182 }
183
184 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result to the
185 /// specified precision and with the specified rounding mode, and taking the first [`Float`] by
186 /// reference and the second by value. An [`Ordering`] is also returned, indicating whether the
187 /// returned value is less than, equal to, or greater than the exact average.
188 ///
189 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
190 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
191 /// is itself in range.
192 ///
193 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
194 /// other than the opposite infinity is that infinity, and the average of the two opposite
195 /// infinities is `NaN`.
196 ///
197 /// $$
198 /// f(x,y,p,m) = \frac{x+y}{2},
199 /// $$
200 ///
201 /// rounded to $p$ bits in the direction specified by $m$.
202 ///
203 /// If you know you'll be using `Nearest`, consider using [`Float::average_prec_ref_val`]
204 /// instead. If you know that your target precision is the maximum of the precisions of the
205 /// inputs, consider using [`Float::average_round_ref_val`] instead.
206 ///
207 /// # Worst-case complexity
208 /// $T(n) = O(n \log n \log\log n)$
209 ///
210 /// $M(n) = O(n)$
211 ///
212 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
213 /// other.significant_bits())`.
214 ///
215 /// # Panics
216 /// Panics if `prec` is zero, or if `rm` is `Exact` but the average is not exactly representable
217 /// with the specified precision.
218 ///
219 /// # Examples
220 /// See [here](super::average#average_prec_round).
221 #[inline]
222 pub fn average_prec_round_ref_val(
223 &self,
224 other: Self,
225 prec: u64,
226 rm: RoundingMode,
227 ) -> (Self, Ordering) {
228 average_prec_round_helper(self.clone(), other, prec, rm)
229 }
230
231 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result to the
232 /// specified precision and with the specified rounding mode, and taking both [`Float`]s by
233 /// reference. An [`Ordering`] is also returned, indicating whether the returned value is less
234 /// than, equal to, or greater than the exact average.
235 ///
236 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
237 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
238 /// is itself in range.
239 ///
240 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
241 /// other than the opposite infinity is that infinity, and the average of the two opposite
242 /// infinities is `NaN`.
243 ///
244 /// $$
245 /// f(x,y,p,m) = \frac{x+y}{2},
246 /// $$
247 ///
248 /// rounded to $p$ bits in the direction specified by $m$.
249 ///
250 /// If you know you'll be using `Nearest`, consider using [`Float::average_prec_ref_ref`]
251 /// instead. If you know that your target precision is the maximum of the precisions of the
252 /// inputs, consider using [`Float::average_round_ref_ref`] instead.
253 ///
254 /// # Worst-case complexity
255 /// $T(n) = O(n \log n \log\log n)$
256 ///
257 /// $M(n) = O(n)$
258 ///
259 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
260 /// other.significant_bits())`.
261 ///
262 /// # Panics
263 /// Panics if `prec` is zero, or if `rm` is `Exact` but the average is not exactly representable
264 /// with the specified precision.
265 ///
266 /// # Examples
267 /// See [here](super::average#average_prec_round).
268 #[inline]
269 pub fn average_prec_round_ref_ref(
270 &self,
271 other: &Self,
272 prec: u64,
273 rm: RoundingMode,
274 ) -> (Self, Ordering) {
275 average_prec_round_helper(self.clone(), other.clone(), prec, rm)
276 }
277
278 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result to the nearest
279 /// value of the specified precision, and taking both [`Float`]s by value. An [`Ordering`] is
280 /// also returned, indicating whether the returned value is less than, equal to, or greater than
281 /// the exact average. If a rounding is a tie, the value with fewer 1s in its binary expansion
282 /// is chosen.
283 ///
284 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
285 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
286 /// is itself in range.
287 ///
288 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
289 /// other than the opposite infinity is that infinity, and the average of the two opposite
290 /// infinities is `NaN`.
291 ///
292 /// $$
293 /// f(x,y,p,m) = \frac{x+y}{2},
294 /// $$
295 ///
296 /// rounded to $p$ bits in the direction specified by $m$.
297 ///
298 /// If you want to specify the rounding mode, consider using [`Float::average_prec_round`]
299 /// instead.
300 ///
301 /// # Worst-case complexity
302 /// $T(n) = O(n \log n \log\log n)$
303 ///
304 /// $M(n) = O(n)$
305 ///
306 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
307 /// other.significant_bits())`.
308 ///
309 /// # Panics
310 /// Panics if `prec` is zero.
311 ///
312 /// # Examples
313 /// See [here](super::average#average_prec).
314 #[inline]
315 pub fn average_prec(self, other: Self, prec: u64) -> (Self, Ordering) {
316 average_prec_round_helper(self, other, prec, Nearest)
317 }
318
319 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result to the nearest
320 /// value of the specified precision, and taking the first [`Float`] by value and the second by
321 /// reference. An [`Ordering`] is also returned, indicating whether the returned value is less
322 /// than, equal to, or greater than the exact average. If a rounding is a tie, the value with
323 /// fewer 1s in its binary expansion is chosen.
324 ///
325 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
326 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
327 /// is itself in range.
328 ///
329 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
330 /// other than the opposite infinity is that infinity, and the average of the two opposite
331 /// infinities is `NaN`.
332 ///
333 /// $$
334 /// f(x,y,p,m) = \frac{x+y}{2},
335 /// $$
336 ///
337 /// rounded to $p$ bits in the direction specified by $m$.
338 ///
339 /// If you want to specify the rounding mode, consider using
340 /// [`Float::average_prec_round_val_ref`] instead.
341 ///
342 /// # Worst-case complexity
343 /// $T(n) = O(n \log n \log\log n)$
344 ///
345 /// $M(n) = O(n)$
346 ///
347 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
348 /// other.significant_bits())`.
349 ///
350 /// # Panics
351 /// Panics if `prec` is zero.
352 ///
353 /// # Examples
354 /// See [here](super::average#average_prec).
355 #[inline]
356 pub fn average_prec_val_ref(self, other: &Self, prec: u64) -> (Self, Ordering) {
357 average_prec_round_helper(self, other.clone(), prec, Nearest)
358 }
359
360 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result to the nearest
361 /// value of the specified precision, and taking the first [`Float`] by reference and the second
362 /// by value. An [`Ordering`] is also returned, indicating whether the returned value is less
363 /// than, equal to, or greater than the exact average. If a rounding is a tie, the value with
364 /// fewer 1s in its binary expansion is chosen.
365 ///
366 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
367 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
368 /// is itself in range.
369 ///
370 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
371 /// other than the opposite infinity is that infinity, and the average of the two opposite
372 /// infinities is `NaN`.
373 ///
374 /// $$
375 /// f(x,y,p,m) = \frac{x+y}{2},
376 /// $$
377 ///
378 /// rounded to $p$ bits in the direction specified by $m$.
379 ///
380 /// If you want to specify the rounding mode, consider using
381 /// [`Float::average_prec_round_ref_val`] instead.
382 ///
383 /// # Worst-case complexity
384 /// $T(n) = O(n \log n \log\log n)$
385 ///
386 /// $M(n) = O(n)$
387 ///
388 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
389 /// other.significant_bits())`.
390 ///
391 /// # Panics
392 /// Panics if `prec` is zero.
393 ///
394 /// # Examples
395 /// See [here](super::average#average_prec).
396 #[inline]
397 pub fn average_prec_ref_val(&self, other: Self, prec: u64) -> (Self, Ordering) {
398 average_prec_round_helper(self.clone(), other, prec, Nearest)
399 }
400
401 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result to the nearest
402 /// value of the specified precision, and taking both [`Float`]s by reference. An [`Ordering`]
403 /// is also returned, indicating whether the returned value is less than, equal to, or greater
404 /// than the exact average. If a rounding is a tie, the value with fewer 1s in its binary
405 /// expansion is chosen.
406 ///
407 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
408 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
409 /// is itself in range.
410 ///
411 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
412 /// other than the opposite infinity is that infinity, and the average of the two opposite
413 /// infinities is `NaN`.
414 ///
415 /// $$
416 /// f(x,y,p,m) = \frac{x+y}{2},
417 /// $$
418 ///
419 /// rounded to $p$ bits in the direction specified by $m$.
420 ///
421 /// If you want to specify the rounding mode, consider using
422 /// [`Float::average_prec_round_ref_ref`] instead.
423 ///
424 /// # Worst-case complexity
425 /// $T(n) = O(n \log n \log\log n)$
426 ///
427 /// $M(n) = O(n)$
428 ///
429 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
430 /// other.significant_bits())`.
431 ///
432 /// # Panics
433 /// Panics if `prec` is zero.
434 ///
435 /// # Examples
436 /// See [here](super::average#average_prec).
437 #[inline]
438 pub fn average_prec_ref_ref(&self, other: &Self, prec: u64) -> (Self, Ordering) {
439 average_prec_round_helper(self.clone(), other.clone(), prec, Nearest)
440 }
441
442 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result with the
443 /// specified rounding mode, and taking both [`Float`]s by value. An [`Ordering`] is also
444 /// returned, indicating whether the returned value is less than, equal to, or greater than the
445 /// exact average.
446 ///
447 /// The precision of the output is the maximum of the precisions of the inputs. See
448 /// [`RoundingMode`] for a description of the possible rounding modes.
449 ///
450 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
451 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
452 /// is itself in range.
453 ///
454 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
455 /// other than the opposite infinity is that infinity, and the average of the two opposite
456 /// infinities is `NaN`.
457 ///
458 /// $$
459 /// f(x,y,p,m) = \frac{x+y}{2},
460 /// $$
461 ///
462 /// rounded to $p$ bits in the direction specified by $m$.
463 ///
464 /// If you want to specify the output precision, consider using [`Float::average_prec_round`]
465 /// instead.
466 ///
467 /// # Worst-case complexity
468 /// $T(n) = O(n \log n \log\log n)$
469 ///
470 /// $M(n) = O(n)$
471 ///
472 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
473 /// other.significant_bits())`.
474 ///
475 /// # Panics
476 /// Panics if `rm` is `Exact` but the average is not exactly representable with the maximum of
477 /// the inputs' precisions.
478 ///
479 /// # Examples
480 /// See [here](super::average#average_round).
481 #[inline]
482 pub fn average_round(self, other: Self, rm: RoundingMode) -> (Self, Ordering) {
483 let prec = max(self.significant_bits(), other.significant_bits());
484 average_prec_round_helper(self, other, prec, rm)
485 }
486
487 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result with the
488 /// specified rounding mode, and taking the first [`Float`] by value and the second by
489 /// reference. An [`Ordering`] is also returned, indicating whether the returned value is less
490 /// than, equal to, or greater than the exact average.
491 ///
492 /// The precision of the output is the maximum of the precisions of the inputs. See
493 /// [`RoundingMode`] for a description of the possible rounding modes.
494 ///
495 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
496 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
497 /// is itself in range.
498 ///
499 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
500 /// other than the opposite infinity is that infinity, and the average of the two opposite
501 /// infinities is `NaN`.
502 ///
503 /// $$
504 /// f(x,y,p,m) = \frac{x+y}{2},
505 /// $$
506 ///
507 /// rounded to $p$ bits in the direction specified by $m$.
508 ///
509 /// If you want to specify the output precision, consider using
510 /// [`Float::average_prec_round_val_ref`] instead.
511 ///
512 /// # Worst-case complexity
513 /// $T(n) = O(n \log n \log\log n)$
514 ///
515 /// $M(n) = O(n)$
516 ///
517 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
518 /// other.significant_bits())`.
519 ///
520 /// # Panics
521 /// Panics if `rm` is `Exact` but the average is not exactly representable with the maximum of
522 /// the inputs' precisions.
523 ///
524 /// # Examples
525 /// See [here](super::average#average_round).
526 #[inline]
527 pub fn average_round_val_ref(self, other: &Self, rm: RoundingMode) -> (Self, Ordering) {
528 let prec = max(self.significant_bits(), other.significant_bits());
529 average_prec_round_helper(self, other.clone(), prec, rm)
530 }
531
532 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result with the
533 /// specified rounding mode, and taking the first [`Float`] by reference and the second by
534 /// value. An [`Ordering`] is also returned, indicating whether the returned value is less than,
535 /// equal to, or greater than the exact average.
536 ///
537 /// The precision of the output is the maximum of the precisions of the inputs. See
538 /// [`RoundingMode`] for a description of the possible rounding modes.
539 ///
540 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
541 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
542 /// is itself in range.
543 ///
544 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
545 /// other than the opposite infinity is that infinity, and the average of the two opposite
546 /// infinities is `NaN`.
547 ///
548 /// $$
549 /// f(x,y,p,m) = \frac{x+y}{2},
550 /// $$
551 ///
552 /// rounded to $p$ bits in the direction specified by $m$.
553 ///
554 /// If you want to specify the output precision, consider using
555 /// [`Float::average_prec_round_ref_val`] instead.
556 ///
557 /// # Worst-case complexity
558 /// $T(n) = O(n \log n \log\log n)$
559 ///
560 /// $M(n) = O(n)$
561 ///
562 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
563 /// other.significant_bits())`.
564 ///
565 /// # Panics
566 /// Panics if `rm` is `Exact` but the average is not exactly representable with the maximum of
567 /// the inputs' precisions.
568 ///
569 /// # Examples
570 /// See [here](super::average#average_round).
571 #[inline]
572 pub fn average_round_ref_val(&self, other: Self, rm: RoundingMode) -> (Self, Ordering) {
573 let prec = max(self.significant_bits(), other.significant_bits());
574 average_prec_round_helper(self.clone(), other, prec, rm)
575 }
576
577 /// Computes the average (arithmetic mean) of two [`Float`]s, rounding the result with the
578 /// specified rounding mode, and taking both [`Float`]s by reference. An [`Ordering`] is also
579 /// returned, indicating whether the returned value is less than, equal to, or greater than the
580 /// exact average.
581 ///
582 /// The precision of the output is the maximum of the precisions of the inputs. See
583 /// [`RoundingMode`] for a description of the possible rounding modes.
584 ///
585 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
586 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
587 /// is itself in range.
588 ///
589 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
590 /// other than the opposite infinity is that infinity, and the average of the two opposite
591 /// infinities is `NaN`.
592 ///
593 /// $$
594 /// f(x,y,p,m) = \frac{x+y}{2},
595 /// $$
596 ///
597 /// rounded to $p$ bits in the direction specified by $m$.
598 ///
599 /// If you want to specify the output precision, consider using
600 /// [`Float::average_prec_round_ref_ref`] instead.
601 ///
602 /// # Worst-case complexity
603 /// $T(n) = O(n \log n \log\log n)$
604 ///
605 /// $M(n) = O(n)$
606 ///
607 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
608 /// other.significant_bits())`.
609 ///
610 /// # Panics
611 /// Panics if `rm` is `Exact` but the average is not exactly representable with the maximum of
612 /// the inputs' precisions.
613 ///
614 /// # Examples
615 /// See [here](super::average#average_round).
616 #[inline]
617 pub fn average_round_ref_ref(&self, other: &Self, rm: RoundingMode) -> (Self, Ordering) {
618 let prec = max(self.significant_bits(), other.significant_bits());
619 average_prec_round_helper(self.clone(), other.clone(), prec, rm)
620 }
621
622 /// Computes the average (arithmetic mean) of two [`Float`]s in place, rounding the result to
623 /// the specified precision and with the specified rounding mode, taking the [`Float`] on the
624 /// right-hand side by value. An [`Ordering`] is returned, indicating whether the assigned value
625 /// is less than, equal to, or greater than the exact average.
626 ///
627 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
628 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
629 /// is itself in range.
630 ///
631 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
632 /// other than the opposite infinity is that infinity, and the average of the two opposite
633 /// infinities is `NaN`.
634 ///
635 /// # Worst-case complexity
636 /// $T(n) = O(n \log n \log\log n)$
637 ///
638 /// $M(n) = O(n)$
639 ///
640 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
641 /// other.significant_bits())`.
642 ///
643 /// # Panics
644 /// Panics if `prec` is zero, or if `rm` is `Exact` but the average is not exactly representable
645 /// with the specified precision.
646 ///
647 /// # Examples
648 /// See [here](super::average#average_prec_round_assign).
649 #[inline]
650 pub fn average_prec_round_assign(
651 &mut self,
652 other: Self,
653 prec: u64,
654 rm: RoundingMode,
655 ) -> Ordering {
656 let (avg, o) = average_prec_round_helper(core::mem::take(self), other, prec, rm);
657 *self = avg;
658 o
659 }
660
661 /// Computes the average (arithmetic mean) of two [`Float`]s in place, rounding the result to
662 /// the specified precision and with the specified rounding mode, taking the [`Float`] on the
663 /// right-hand side by reference. An [`Ordering`] is returned, indicating whether the assigned
664 /// value is less than, equal to, or greater than the exact average.
665 ///
666 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
667 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
668 /// is itself in range.
669 ///
670 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
671 /// other than the opposite infinity is that infinity, and the average of the two opposite
672 /// infinities is `NaN`.
673 ///
674 /// # Worst-case complexity
675 /// $T(n) = O(n \log n \log\log n)$
676 ///
677 /// $M(n) = O(n)$
678 ///
679 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
680 /// other.significant_bits())`.
681 ///
682 /// # Panics
683 /// Panics if `prec` is zero, or if `rm` is `Exact` but the average is not exactly representable
684 /// with the specified precision.
685 ///
686 /// # Examples
687 /// See [here](super::average#average_prec_round_assign_ref).
688 #[inline]
689 pub fn average_prec_round_assign_ref(
690 &mut self,
691 other: &Self,
692 prec: u64,
693 rm: RoundingMode,
694 ) -> Ordering {
695 let (avg, o) = average_prec_round_helper(core::mem::take(self), other.clone(), prec, rm);
696 *self = avg;
697 o
698 }
699
700 /// Computes the average (arithmetic mean) of two [`Float`]s in place, rounding the result to
701 /// the nearest value of the specified precision, taking the [`Float`] on the right-hand side by
702 /// value. An [`Ordering`] is returned, indicating whether the assigned value is less than,
703 /// equal to, or greater than the exact average.
704 ///
705 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
706 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
707 /// is itself in range.
708 ///
709 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
710 /// other than the opposite infinity is that infinity, and the average of the two opposite
711 /// infinities is `NaN`.
712 ///
713 /// # Worst-case complexity
714 /// $T(n) = O(n \log n \log\log n)$
715 ///
716 /// $M(n) = O(n)$
717 ///
718 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
719 /// other.significant_bits())`.
720 ///
721 /// # Panics
722 /// Panics if `prec` is zero.
723 ///
724 /// # Examples
725 /// See [here](super::average#average_prec_assign).
726 #[inline]
727 pub fn average_prec_assign(&mut self, other: Self, prec: u64) -> Ordering {
728 let (avg, o) = average_prec_round_helper(core::mem::take(self), other, prec, Nearest);
729 *self = avg;
730 o
731 }
732
733 /// Computes the average (arithmetic mean) of two [`Float`]s in place, rounding the result to
734 /// the nearest value of the specified precision, taking the [`Float`] on the right-hand side by
735 /// reference. An [`Ordering`] is returned, indicating whether the assigned value is less than,
736 /// equal to, or greater than the exact average.
737 ///
738 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
739 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
740 /// is itself in range.
741 ///
742 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
743 /// other than the opposite infinity is that infinity, and the average of the two opposite
744 /// infinities is `NaN`.
745 ///
746 /// # Worst-case complexity
747 /// $T(n) = O(n \log n \log\log n)$
748 ///
749 /// $M(n) = O(n)$
750 ///
751 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
752 /// other.significant_bits())`.
753 ///
754 /// # Panics
755 /// Panics if `prec` is zero.
756 ///
757 /// # Examples
758 /// See [here](super::average#average_prec_assign_ref).
759 #[inline]
760 pub fn average_prec_assign_ref(&mut self, other: &Self, prec: u64) -> Ordering {
761 let (avg, o) =
762 average_prec_round_helper(core::mem::take(self), other.clone(), prec, Nearest);
763 *self = avg;
764 o
765 }
766
767 /// Computes the average (arithmetic mean) of two [`Float`]s in place, rounding the result with
768 /// the specified rounding mode and taking the [`Float`] on the right-hand side by value. An
769 /// [`Ordering`] is returned, indicating whether the assigned value is less than, equal to, or
770 /// greater than the exact average.
771 ///
772 /// The precision of the output is the maximum of the precisions of the inputs.
773 ///
774 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
775 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
776 /// is itself in range.
777 ///
778 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
779 /// other than the opposite infinity is that infinity, and the average of the two opposite
780 /// infinities is `NaN`.
781 ///
782 /// # Worst-case complexity
783 /// $T(n) = O(n \log n \log\log n)$
784 ///
785 /// $M(n) = O(n)$
786 ///
787 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
788 /// other.significant_bits())`.
789 ///
790 /// # Panics
791 /// Panics if `rm` is `Exact` but the average is not exactly representable with the maximum of
792 /// the inputs' precisions.
793 ///
794 /// # Examples
795 /// See [here](super::average#average_round_assign).
796 #[inline]
797 pub fn average_round_assign(&mut self, other: Self, rm: RoundingMode) -> Ordering {
798 let prec = max(self.significant_bits(), other.significant_bits());
799 let (avg, o) = average_prec_round_helper(core::mem::take(self), other, prec, rm);
800 *self = avg;
801 o
802 }
803
804 /// Computes the average (arithmetic mean) of two [`Float`]s in place, rounding the result with
805 /// the specified rounding mode and taking the [`Float`] on the right-hand side by reference. An
806 /// [`Ordering`] is returned, indicating whether the assigned value is less than, equal to, or
807 /// greater than the exact average.
808 ///
809 /// The precision of the output is the maximum of the precisions of the inputs.
810 ///
811 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
812 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
813 /// is itself in range.
814 ///
815 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
816 /// other than the opposite infinity is that infinity, and the average of the two opposite
817 /// infinities is `NaN`.
818 ///
819 /// # Worst-case complexity
820 /// $T(n) = O(n \log n \log\log n)$
821 ///
822 /// $M(n) = O(n)$
823 ///
824 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
825 /// other.significant_bits())`.
826 ///
827 /// # Panics
828 /// Panics if `rm` is `Exact` but the average is not exactly representable with the maximum of
829 /// the inputs' precisions.
830 ///
831 /// # Examples
832 /// See [here](super::average#average_round_assign_ref).
833 #[inline]
834 pub fn average_round_assign_ref(&mut self, other: &Self, rm: RoundingMode) -> Ordering {
835 let prec = max(self.significant_bits(), other.significant_bits());
836 let (avg, o) = average_prec_round_helper(core::mem::take(self), other.clone(), prec, rm);
837 *self = avg;
838 o
839 }
840}
841
842impl Average<Self> for Float {
843 type Output = Self;
844
845 /// Computes the average (arithmetic mean) of two [`Float`]s, taking both [`Float`]s by value.
846 ///
847 /// The precision of the output is the maximum of the precisions of the inputs, and the result
848 /// is rounded to nearest, with ties going to the value whose binary expansion has fewer 1s. If
849 /// you want to specify the precision or the rounding mode, consider using
850 /// [`Float::average_prec_round`] instead; that form also reports how the returned value
851 /// compares with the exact average.
852 ///
853 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
854 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
855 /// is itself in range.
856 ///
857 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
858 /// other than the opposite infinity is that infinity, and the average of the two opposite
859 /// infinities is `NaN`.
860 ///
861 /// $$
862 /// f(x,y) = \frac{x+y}{2},
863 /// $$
864 ///
865 /// rounded to nearest.
866 ///
867 /// # Worst-case complexity
868 /// $T(n) = O(n \log n \log\log n)$
869 ///
870 /// $M(n) = O(n)$
871 ///
872 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
873 /// other.significant_bits())`.
874 ///
875 /// # Examples
876 /// See [here](super::average#average).
877 #[inline]
878 fn average(self, other: Self) -> Self {
879 let prec = max(self.significant_bits(), other.significant_bits());
880 average_prec_round_helper(self, other, prec, Nearest).0
881 }
882}
883
884impl Average<&Self> for Float {
885 type Output = Self;
886
887 /// Computes the average (arithmetic mean) of two [`Float`]s, taking the first [`Float`] by
888 /// value and the second by reference.
889 ///
890 /// The precision of the output is the maximum of the precisions of the inputs, and the result
891 /// is rounded to nearest, with ties going to the value whose binary expansion has fewer 1s. If
892 /// you want to specify the precision or the rounding mode, consider using
893 /// [`Float::average_prec_round_val_ref`] instead; that form also reports how the returned value
894 /// compares with the exact average.
895 ///
896 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
897 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
898 /// is itself in range.
899 ///
900 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
901 /// other than the opposite infinity is that infinity, and the average of the two opposite
902 /// infinities is `NaN`.
903 ///
904 /// $$
905 /// f(x,y) = \frac{x+y}{2},
906 /// $$
907 ///
908 /// rounded to nearest.
909 ///
910 /// # Worst-case complexity
911 /// $T(n) = O(n \log n \log\log n)$
912 ///
913 /// $M(n) = O(n)$
914 ///
915 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
916 /// other.significant_bits())`.
917 ///
918 /// # Examples
919 /// See [here](super::average#average).
920 #[inline]
921 fn average(self, other: &Self) -> Self {
922 let prec = max(self.significant_bits(), other.significant_bits());
923 average_prec_round_helper(self, other.clone(), prec, Nearest).0
924 }
925}
926
927impl Average<Float> for &Float {
928 type Output = Float;
929
930 /// Computes the average (arithmetic mean) of two [`Float`]s, taking the first [`Float`] by
931 /// reference and the second by value.
932 ///
933 /// The precision of the output is the maximum of the precisions of the inputs, and the result
934 /// is rounded to nearest, with ties going to the value whose binary expansion has fewer 1s. If
935 /// you want to specify the precision or the rounding mode, consider using
936 /// [`Float::average_prec_round_ref_val`] instead; that form also reports how the returned value
937 /// compares with the exact average.
938 ///
939 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
940 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
941 /// is itself in range.
942 ///
943 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
944 /// other than the opposite infinity is that infinity, and the average of the two opposite
945 /// infinities is `NaN`.
946 ///
947 /// $$
948 /// f(x,y) = \frac{x+y}{2},
949 /// $$
950 ///
951 /// rounded to nearest.
952 ///
953 /// # Worst-case complexity
954 /// $T(n) = O(n \log n \log\log n)$
955 ///
956 /// $M(n) = O(n)$
957 ///
958 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
959 /// other.significant_bits())`.
960 ///
961 /// # Examples
962 /// See [here](super::average#average).
963 #[inline]
964 fn average(self, other: Float) -> Float {
965 let prec = max(self.significant_bits(), other.significant_bits());
966 average_prec_round_helper(self.clone(), other, prec, Nearest).0
967 }
968}
969
970impl Average<&Float> for &Float {
971 type Output = Float;
972
973 /// Computes the average (arithmetic mean) of two [`Float`]s, taking both [`Float`]s by
974 /// reference.
975 ///
976 /// The precision of the output is the maximum of the precisions of the inputs, and the result
977 /// is rounded to nearest, with ties going to the value whose binary expansion has fewer 1s. If
978 /// you want to specify the precision or the rounding mode, consider using
979 /// [`Float::average_prec_round_ref_ref`] instead; that form also reports how the returned value
980 /// compares with the exact average.
981 ///
982 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
983 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
984 /// is itself in range.
985 ///
986 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
987 /// other than the opposite infinity is that infinity, and the average of the two opposite
988 /// infinities is `NaN`.
989 ///
990 /// $$
991 /// f(x,y) = \frac{x+y}{2},
992 /// $$
993 ///
994 /// rounded to nearest.
995 ///
996 /// # Worst-case complexity
997 /// $T(n) = O(n \log n \log\log n)$
998 ///
999 /// $M(n) = O(n)$
1000 ///
1001 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
1002 /// other.significant_bits())`.
1003 ///
1004 /// # Examples
1005 /// See [here](super::average#average).
1006 #[inline]
1007 fn average(self, other: &Float) -> Float {
1008 let prec = max(self.significant_bits(), other.significant_bits());
1009 average_prec_round_helper(self.clone(), other.clone(), prec, Nearest).0
1010 }
1011}
1012
1013impl AverageAssign<Self> for Float {
1014 /// Computes the average (arithmetic mean) of two [`Float`]s in place, taking the [`Float`] on
1015 /// the right-hand side by value.
1016 ///
1017 /// The precision of the output is the maximum of the precisions of the inputs, and the result
1018 /// is rounded to nearest.
1019 ///
1020 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
1021 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
1022 /// is itself in range.
1023 ///
1024 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
1025 /// other than the opposite infinity is that infinity, and the average of the two opposite
1026 /// infinities is `NaN`.
1027 ///
1028 /// # Worst-case complexity
1029 /// $T(n) = O(n \log n \log\log n)$
1030 ///
1031 /// $M(n) = O(n)$
1032 ///
1033 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
1034 /// other.significant_bits())`.
1035 ///
1036 /// # Examples
1037 /// See [here](super::average#average_assign).
1038 #[inline]
1039 fn average_assign(&mut self, other: Self) {
1040 let prec = max(self.significant_bits(), other.significant_bits());
1041 *self = average_prec_round_helper(core::mem::take(self), other, prec, Nearest).0;
1042 }
1043}
1044
1045impl AverageAssign<&Self> for Float {
1046 /// Computes the average (arithmetic mean) of two [`Float`]s in place, taking the [`Float`] on
1047 /// the right-hand side by reference.
1048 ///
1049 /// The precision of the output is the maximum of the precisions of the inputs, and the result
1050 /// is rounded to nearest.
1051 ///
1052 /// The average is computed as though with unbounded exponent range and rounded exactly once, so
1053 /// a sum that would overflow, or a halving that would underflow, does not spoil a result that
1054 /// is itself in range.
1055 ///
1056 /// If either input is `NaN`, the result is `NaN`; the average of an infinity and any value
1057 /// other than the opposite infinity is that infinity, and the average of the two opposite
1058 /// infinities is `NaN`.
1059 ///
1060 /// # Worst-case complexity
1061 /// $T(n) = O(n \log n \log\log n)$
1062 ///
1063 /// $M(n) = O(n)$
1064 ///
1065 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(prec, self.significant_bits(),
1066 /// other.significant_bits())`.
1067 ///
1068 /// # Examples
1069 /// See [here](super::average#average_assign).
1070 #[inline]
1071 fn average_assign(&mut self, other: &Self) {
1072 let prec = max(self.significant_bits(), other.significant_bits());
1073 *self = average_prec_round_helper(core::mem::take(self), other.clone(), prec, Nearest).0;
1074 }
1075}