malachite_nz/natural/arithmetic/shr_round.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5// Copyright © 1991, 1993, 1994, 1996, 1998, 1999, 2001, 2002, 2004, 2012, 2015 Free Software
6// Foundation, Inc.
7//
8// This file is part of Malachite.
9//
10// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
11// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
12// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
13
14use crate::natural::InnerNatural::{Large, Small};
15use crate::natural::arithmetic::add::limbs_vec_add_limb_in_place;
16use crate::natural::arithmetic::divisible_by_power_of_2::limbs_divisible_by_power_of_2;
17use crate::natural::arithmetic::shr::{
18 limbs_shr, limbs_slice_shr_in_place, limbs_vec_shr_in_place,
19};
20use crate::natural::logic::bit_access::limbs_get_bit;
21use crate::natural::{Natural, bit_to_limb_count_floor};
22use crate::platform::Limb;
23use alloc::vec::Vec;
24use core::cmp::Ordering::{self, *};
25use core::ops::{Shl, ShlAssign};
26use malachite_base::num::arithmetic::traits::{Parity, ShrRound, ShrRoundAssign, UnsignedAbs};
27use malachite_base::num::basic::integers::PrimitiveInt;
28use malachite_base::num::basic::signeds::PrimitiveSigned;
29use malachite_base::num::basic::traits::Zero;
30use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
31use malachite_base::num::conversion::traits::ExactFrom;
32use malachite_base::rounding_modes::RoundingMode::{self, *};
33use malachite_base::slices::slice_test_zero;
34use malachite_base::vecs::vec_delete_left;
35
36// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, returns the
37// limbs of the `Natural` right-shifted by a `Limb`, rounding up. The limbs should not all be zero.
38//
39// # Worst-case complexity
40// $T(n) = O(n)$
41//
42// $M(n) = O(n)$
43//
44// where $T$ is time, $M$ is additional memory and $n$ is `max(1, xs.len() - bits / Limb::WIDTH)`.
45//
46// This is equivalent to `cfdiv_q_2exp` from `mpz/cfdiv_q_2exp.c`, GMP 6.2.1, where `u` is
47// non-negative, `dir == 1`, and the result is returned.
48pub_test! {limbs_shr_round_up(xs: &[Limb], bits: u64) -> (Vec<Limb>, Ordering) {
49 let delete_count = bit_to_limb_count_floor(bits);
50 if delete_count >= xs.len() {
51 (vec![1], Greater)
52 } else {
53 let (xs_lo, xs_hi) = xs.split_at(delete_count);
54 let mut exact = slice_test_zero(xs_lo);
55 let mut out = xs_hi.to_vec();
56 let small_bits = bits & Limb::WIDTH_MASK;
57 if small_bits != 0 {
58 exact &= limbs_slice_shr_in_place(&mut out, small_bits) == 0;
59 }
60 if !exact {
61 limbs_vec_add_limb_in_place(&mut out, 1);
62 }
63 (
64 out,
65 if exact {
66 Equal
67 } else {
68 Greater
69 },
70 )
71 }
72}}
73
74// # Worst-case complexity
75// $T(n) = O(n)$
76//
77// $M(n) = O(n)$
78//
79// where $T$ is time, $M$ is additional memory and $n$ is `max(1, xs.len() - bits / Limb::WIDTH)`.
80fn limbs_shr_round_half_integer_to_even(xs: &[Limb], bits: u64) -> (Vec<Limb>, Ordering) {
81 let delete_count = bit_to_limb_count_floor(bits);
82 if delete_count >= xs.len() {
83 (Vec::new(), if slice_test_zero(xs) { Equal } else { Less })
84 } else {
85 let small_bits = bits & Limb::WIDTH_MASK;
86 let (xs_lo, xs_hi) = xs.split_at(delete_count);
87 let mut exact = slice_test_zero(xs_lo);
88 let mut out = xs_hi.to_vec();
89 if small_bits != 0 {
90 exact &= limbs_slice_shr_in_place(&mut out, small_bits) == 0;
91 }
92 if !out.is_empty() && out[0].odd() {
93 limbs_vec_add_limb_in_place(&mut out, 1);
94 (out, Greater)
95 } else {
96 (out, if exact { Equal } else { Less })
97 }
98 }
99}
100
101// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, returns the
102// limbs of the `Natural` right-shifted by a `Limb`, rounding to the `Natural` nearest to the actual
103// value of `self` divided by `2 ^ bits`. If the actual value is exactly between two integers, it is
104// rounded to the even one.
105//
106// # Worst-case complexity
107// $T(n) = O(n)$
108//
109// $M(m) = O(m)$
110//
111// where $T$ is time, $M$ is additional memory, $n$ is `xs.len()`, and $m$ is `max(1, xs.len() -
112// bits / Limb::WIDTH)`.
113pub_test! {limbs_shr_round_nearest(xs: &[Limb], bits: u64) -> (Vec<Limb>, Ordering) {
114 if bits == 0 {
115 (xs.to_vec(), Equal)
116 } else {
117 let d = slice_test_zero(xs) || limbs_divisible_by_power_of_2(xs, bits - 1);
118 if !limbs_get_bit(xs, bits - 1) {
119 (
120 limbs_shr(xs, bits),
121 if d { Equal } else { Less },
122 )
123 } else if d {
124 limbs_shr_round_half_integer_to_even(xs, bits)
125 } else {
126 limbs_shr_round_up(xs, bits)
127 }
128 }
129}}
130
131// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, returns the
132// limbs of the `Natural` right-shifted by a `Limb`, if the shift is exact (doesn't remove any
133// `true` bits). If the shift is inexact, `None` is returned. The limbs should not all be zero.
134//
135// # Worst-case complexity
136// $T(n) = O(n)$
137//
138// $M(n) = O(m)$
139//
140// where $T$ is time, $M$ is additional memory, $n$ is `xs.len()`, and $m$ is `max(1, xs.len() -
141// bits / Limb::WIDTH)`.
142pub_test! {limbs_shr_exact(xs: &[Limb], bits: u64) -> Option<Vec<Limb>> {
143 if limbs_divisible_by_power_of_2(xs, bits) {
144 Some(limbs_shr(xs, bits))
145 } else {
146 None
147 }
148}}
149
150// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, returns the
151// limbs of the `Natural` right-shifted by a `Limb`, rounded using a specified rounding format. The
152// limbs should not all be zero.
153//
154// # Worst-case complexity
155// $T(n) = O(n)$
156//
157// $M(m) = O(m)$
158//
159// where $T$ is time, $M$ is additional memory, $n$ is `xs.len()`, and $m$ is `max(1, xs.len() -
160// bits / Limb::WIDTH)`.
161pub_test! {
162 limbs_shr_round(xs: &[Limb], bits: u64, rm: RoundingMode) -> Option<(Vec<Limb>, Ordering)> {
163 match rm {
164 Down | Floor => Some((
165 limbs_shr(xs, bits),
166 if limbs_divisible_by_power_of_2(xs, bits) {
167 Equal
168 } else {
169 Less
170 },
171 )),
172 Up | Ceiling => Some(limbs_shr_round_up(xs, bits)),
173 Nearest => Some(limbs_shr_round_nearest(xs, bits)),
174 Exact => limbs_shr_exact(xs, bits).map(|ss| (ss, Equal)),
175 }
176}}
177
178// Interpreting a `Vec` of `Limb`s as the limbs (in ascending order) of a `Natural`, writes the
179// limbs of the `Natural` right-shifted by a `Limb`, rounding up, to the input `Vec`. The limbs
180// should not all be zero.
181//
182// # Worst-case complexity
183// $T(n) = O(n)$
184//
185// $M(n) = O(1)$
186//
187// where $T$ is time, $M$ is additional memory and $n$ is `max(1, xs.len() - bits / Limb::WIDTH)`.
188//
189// This is equivalent to `cfdiv_q_2exp` from `mpz/cfdiv_q_2exp.c`, GMP 6.2.1, where `u` is
190// non-negative, `dir == 1`, and `w == u`.
191pub_test! {limbs_vec_shr_round_up_in_place(xs: &mut Vec<Limb>, bits: u64) -> Ordering {
192 let delete_count = bit_to_limb_count_floor(bits);
193 if delete_count >= xs.len() {
194 xs.truncate(1);
195 xs[0] = 1;
196 Greater
197 } else {
198 let mut exact = slice_test_zero(&xs[..delete_count]);
199 let small_bits = bits & Limb::WIDTH_MASK;
200 vec_delete_left(xs, delete_count);
201 if small_bits != 0 {
202 exact &= limbs_slice_shr_in_place(xs, small_bits) == 0;
203 }
204 if !exact {
205 limbs_vec_add_limb_in_place(xs, 1);
206 }
207 if exact {
208 Equal
209 } else {
210 Greater
211 }
212 }
213}}
214
215// # Worst-case complexity
216// $T(n) = O(n)$
217//
218// $M(n) = O(1)$
219//
220// where $T$ is time, $M$ is additional memory and $n$ is `max(1, xs.len() - bits / Limb::WIDTH)`.
221fn limbs_vec_shr_round_half_integer_to_even_in_place(xs: &mut Vec<Limb>, bits: u64) -> Ordering {
222 let delete_count = bit_to_limb_count_floor(bits);
223 if delete_count >= xs.len() {
224 let o = if slice_test_zero(xs) { Equal } else { Less };
225 xs.clear();
226 o
227 } else {
228 let small_bits = bits & Limb::WIDTH_MASK;
229 let mut exact = slice_test_zero(&xs[..delete_count]);
230 vec_delete_left(xs, delete_count);
231 if small_bits != 0 {
232 exact &= limbs_slice_shr_in_place(xs, small_bits) == 0;
233 }
234 if !xs.is_empty() && xs[0].odd() {
235 limbs_vec_add_limb_in_place(xs, 1);
236 Greater
237 } else if exact {
238 Equal
239 } else {
240 Less
241 }
242 }
243}
244
245// Interpreting a `Vec` of `Limb`s as the limbs (in ascending order) of a `Natural`, writes the
246// limbs of the `Natural` right-shifted by a `Limb` to the input `Vec`, rounding to the `Natural`
247// nearest to the actual value of `self` divided by `2 ^ bits`. If the actual value is exactly
248// between two integers, it is rounded to the even one.
249//
250// # Worst-case complexity
251// $T(n) = O(n)$
252//
253// $M(n) = O(1)$
254//
255// where $T$ is time, $M$ is additional memory and $n$ is `xs.len()`.
256pub_test! {limbs_vec_shr_round_nearest_in_place(xs: &mut Vec<Limb>, bits: u64) -> Ordering {
257 if bits == 0 {
258 Equal
259 } else {
260 let d = slice_test_zero(xs) || limbs_divisible_by_power_of_2(xs, bits - 1);
261 if !limbs_get_bit(xs, bits - 1) {
262 limbs_vec_shr_in_place(xs, bits);
263 if d {
264 Equal
265 } else {
266 Less
267 }
268 } else if d {
269 limbs_vec_shr_round_half_integer_to_even_in_place(xs, bits)
270 } else {
271 limbs_vec_shr_round_up_in_place(xs, bits)
272 }
273 }
274}}
275
276// Interpreting a `Vec` of `Limb`s as the limbs (in ascending order) of a `Natural`, writes the
277// limbs of the `Natural` right-shifted by a `Limb` to the input `Vec`, if the shift is exact
278// (doesn't remove any `true` bits). Returns whether the shift was exact. The limbs should not all
279// be zero.
280//
281// # Worst-case complexity
282// $T(n) = O(n)$
283//
284// $M(n) = O(1)$
285//
286// where $T$ is time, $M$ is additional memory and $n$ is `xs.len()`.
287pub_test! {limbs_vec_shr_exact_in_place(xs: &mut Vec<Limb>, bits: u64) -> bool {
288 if limbs_divisible_by_power_of_2(xs, bits) {
289 limbs_vec_shr_in_place(xs, bits);
290 true
291 } else {
292 false
293 }
294}}
295
296// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, writes the
297// limbs of the `Natural` right-shifted by a `Limb` to the input `Vec`, rounded using a specified
298// rounding format. If the shift is inexact (removes some `true` bits) and the `RoundingMode` is
299// `Exact`, the value of `xs` becomes unspecified and `false` is returned. Otherwise, `true` is
300// returned. The limbs should not all be zero.
301//
302// # Worst-case complexity
303// $T(n) = O(n)$
304//
305// $M(n) = O(1)$
306//
307// where $T$ is time, $M$ is additional memory and $n$ is `xs.len()`.
308pub_test! {limbs_vec_shr_round_in_place(
309 xs: &mut Vec<Limb>,
310 bits: u64,
311 rm: RoundingMode,
312) -> (bool, Ordering) {
313 match rm {
314 Down | Floor => {
315 let exact = limbs_divisible_by_power_of_2(xs, bits);
316 limbs_vec_shr_in_place(xs, bits);
317 (
318 true,
319 if exact {
320 Equal
321 } else {
322 Less
323 },
324 )
325 }
326 Up | Ceiling => {
327 (true, limbs_vec_shr_round_up_in_place(xs, bits))
328 }
329 Nearest => (true, limbs_vec_shr_round_nearest_in_place(xs, bits)),
330 Exact => (limbs_vec_shr_exact_in_place(xs, bits), Equal),
331 }
332}}
333
334fn shr_round_unsigned_ref_n<T: PrimitiveUnsigned>(
335 x: &Natural,
336 bits: T,
337 rm: RoundingMode,
338) -> (Natural, Ordering)
339where
340 u64: ExactFrom<T>,
341 Limb: ShrRound<T, Output = Limb>,
342{
343 match (x, bits) {
344 (&Natural::ZERO, _) => (x.clone(), Equal),
345 (_, bits) if bits == T::ZERO => (x.clone(), Equal),
346 (Natural(Small(small)), bits) => {
347 let (s, o) = small.shr_round(bits, rm);
348 (Natural(Small(s)), o)
349 }
350 (Natural(Large(limbs)), bits) => {
351 if let Some((out, o)) = limbs_shr_round(limbs, u64::exact_from(bits), rm) {
352 (Natural::from_owned_limbs_asc(out), o)
353 } else {
354 panic!("Right shift is not exact: {x} >> {bits}");
355 }
356 }
357 }
358}
359
360fn shr_round_assign_unsigned_n<T: PrimitiveUnsigned>(
361 x: &mut Natural,
362 bits: T,
363 rm: RoundingMode,
364) -> Ordering
365where
366 u64: ExactFrom<T>,
367 Limb: ShrRoundAssign<T>,
368{
369 match (&mut *x, bits) {
370 (&mut Natural::ZERO, _) => Equal,
371 (_, bits) if bits == T::ZERO => Equal,
372 (Natural(Small(small)), bits) => small.shr_round_assign(bits, rm),
373 (Natural(Large(limbs)), bits) => {
374 let (b, o) = limbs_vec_shr_round_in_place(limbs, u64::exact_from(bits), rm);
375 assert!(b, "Right shift is not exact.");
376 x.trim();
377 o
378 }
379 }
380}
381
382macro_rules! impl_natural_shr_round_unsigned {
383 ($t:ident) => {
384 impl ShrRound<$t> for Natural {
385 type Output = Natural;
386
387 /// Shifts a [`Natural`] right (divides it by a power of 2), taking it by value, and
388 /// rounds according to the specified rounding mode. An [`Ordering`] is also returned,
389 /// indicating whether the returned value is less than, equal to, or greater than the
390 /// exact value.
391 ///
392 /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether `Exact` can
393 /// be passed, use `self.divisible_by_power_of_2(bits)`.
394 ///
395 /// Let $q = \frac{x}{2^k}$, and let $g$ be the function that just returns the first
396 /// element of the pair, without the [`Ordering`]:
397 ///
398 /// $f(x, k, \mathrm{Down}) = f(x, y, \mathrm{Floor}) = \lfloor q \rfloor.$
399 ///
400 /// $f(x, k, \mathrm{Up}) = f(x, y, \mathrm{Ceiling}) = \lceil q \rceil.$
401 ///
402 /// $$
403 /// f(x, k, \mathrm{Nearest}) = \begin{cases}
404 /// \lfloor q \rfloor & \text{if}
405 /// \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\
406 /// \lceil q \rceil & \text{if}
407 /// \\quad q - \lfloor q \rfloor > \frac{1}{2}, \\\\
408 /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor =
409 /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor
410 /// \\ \text{is even}, \\\\
411 /// \lceil q \rceil &
412 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
413 /// \\ \lfloor q \rfloor \\ \text{is odd}.
414 /// \end{cases}
415 /// $$
416 ///
417 /// $f(x, k, \mathrm{Exact}) = q$, but panics if $q \notin \N$.
418 ///
419 /// Then
420 ///
421 /// $f(x, k, r) = (g(x, k, r), \operatorname{cmp}(g(x, k, r), q))$.
422 ///
423 /// # Worst-case complexity
424 /// $T(n) = O(n)$
425 ///
426 /// $M(n) = O(1)$
427 ///
428 /// where $T$ is time, $M$ is additional memory and $n$ is `self.significant_bits()`.
429 ///
430 /// # Panics
431 /// Let $k$ be `bits`. Panics if `rm` is `Exact` but `self` is not divisible by $2^k$.
432 ///
433 /// # Examples
434 /// See [here](super::shr_round#shr_round).
435 #[inline]
436 fn shr_round(mut self, bits: $t, rm: RoundingMode) -> (Natural, Ordering) {
437 let o = self.shr_round_assign(bits, rm);
438 (self, o)
439 }
440 }
441
442 impl<'a> ShrRound<$t> for &Natural {
443 type Output = Natural;
444
445 /// Shifts a [`Natural`] right (divides it by a power of 2), taking it by reference, and
446 /// rounds according to the specified rounding mode. An [`Ordering`] is also returned,
447 /// indicating whether the returned value is less than, equal to, or greater than the
448 /// exact value.
449 ///
450 /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether `Exact` can
451 /// be passed, use `self.divisible_by_power_of_2(bits)`.
452 ///
453 /// Let $q = \frac{x}{2^k}$, and let $g$ be the function that just returns the first
454 /// element of the pair, without the [`Ordering`]:
455 ///
456 /// $f(x, k, \mathrm{Down}) = f(x, y, \mathrm{Floor}) = \lfloor q \rfloor.$
457 ///
458 /// $f(x, k, \mathrm{Up}) = f(x, y, \mathrm{Ceiling}) = \lceil q \rceil.$
459 ///
460 /// $$
461 /// f(x, k, \mathrm{Nearest}) = \begin{cases}
462 /// \lfloor q \rfloor & \text{if}
463 /// \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\
464 /// \lceil q \rceil & \text{if}
465 /// \\quad q - \lfloor q \rfloor > \frac{1}{2}, \\\\
466 /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor =
467 /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor
468 /// \\ \text{is even}, \\\\
469 /// \lceil q \rceil &
470 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
471 /// \\ \lfloor q \rfloor \\ \text{is odd}.
472 /// \end{cases}
473 /// $$
474 ///
475 /// $f(x, k, \mathrm{Exact}) = q$, but panics if $q \notin \N$.
476 ///
477 /// Then
478 ///
479 /// $f(x, k, r) = (g(x, k, r), \operatorname{cmp}(g(x, k, r), q))$.
480 ///
481 /// # Worst-case complexity
482 /// $T(n) = O(n)$
483 ///
484 /// $M(m) = O(m)$
485 ///
486 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and
487 /// $m$ is `max(1, self.significant_bits() - bits)`.
488 ///
489 /// # Panics
490 /// Let $k$ be `bits`. Panics if `rm` is `Exact` but `self` is not divisible by $2^k$.
491 ///
492 /// # Examples
493 /// See [here](super::shr_round#shr_round).
494 #[inline]
495 fn shr_round(self, bits: $t, rm: RoundingMode) -> (Natural, Ordering) {
496 shr_round_unsigned_ref_n(self, bits, rm)
497 }
498 }
499
500 impl ShrRoundAssign<$t> for Natural {
501 /// Shifts a [`Natural`] right (divides it by a power of 2) and rounds according to the
502 /// specified rounding mode, in place. An [`Ordering`] is returned, indicating whether
503 /// the assigned value is less than, equal to, or greater than the exact value.
504 ///
505 /// Passing `Floor` or `Down` is equivalent to using `>>=`. To test whether `Exact` can
506 /// be passed, use `self.divisible_by_power_of_2(bits)`.
507 ///
508 /// See the [`ShrRound`] documentation for details.
509 ///
510 /// # Worst-case complexity
511 /// $T(n) = O(n)$
512 ///
513 /// $M(n) = O(1)$
514 ///
515 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
516 ///
517 /// # Panics
518 /// Let $k$ be `bits`. Panics if `rm` is `Exact` but `self` is not divisible by $2^k$.
519 ///
520 /// # Examples
521 /// See [here](super::shr_round#shr_round_assign).
522 #[inline]
523 fn shr_round_assign(&mut self, bits: $t, rm: RoundingMode) -> Ordering {
524 shr_round_assign_unsigned_n(self, bits, rm)
525 }
526 }
527 };
528}
529apply_to_unsigneds!(impl_natural_shr_round_unsigned);
530
531fn shr_round_signed_ref_n<'a, U, S: PrimitiveSigned + UnsignedAbs<Output = U>>(
532 x: &'a Natural,
533 bits: S,
534 rm: RoundingMode,
535) -> (Natural, Ordering)
536where
537 &'a Natural: Shl<U, Output = Natural> + ShrRound<U, Output = Natural>,
538{
539 if bits >= S::ZERO {
540 x.shr_round(bits.unsigned_abs(), rm)
541 } else {
542 (x << bits.unsigned_abs(), Equal)
543 }
544}
545
546fn shr_round_assign_signed_n<U, S: PrimitiveSigned + UnsignedAbs<Output = U>>(
547 x: &mut Natural,
548 bits: S,
549 rm: RoundingMode,
550) -> Ordering
551where
552 Natural: ShlAssign<U> + ShrRoundAssign<U>,
553{
554 if bits >= S::ZERO {
555 x.shr_round_assign(bits.unsigned_abs(), rm)
556 } else {
557 *x <<= bits.unsigned_abs();
558 Equal
559 }
560}
561
562macro_rules! impl_natural_shr_round_signed {
563 ($t:ident) => {
564 impl ShrRound<$t> for Natural {
565 type Output = Natural;
566
567 /// Shifts a [`Natural`] right (divides or multiplies it by a power of 2), taking it by
568 /// value, and rounds according to the specified rounding mode. An [`Ordering`] is also
569 /// returned, indicating whether the returned value is less than, equal to, or greater
570 /// than the exact value. If `bits` is negative, then the returned [`Ordering`] is
571 /// always `Equal`, even if the higher bits of the result are lost.
572 ///
573 /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether `Exact` can
574 /// be passed, use `self.divisible_by_power_of_2(bits)`.
575 ///
576 /// Let $q = \frac{x}{2^k}$, and let $g$ be the function that just returns the first
577 /// element of the pair, without the [`Ordering`]:
578 ///
579 /// $f(x, k, \mathrm{Down}) = f(x, y, \mathrm{Floor}) = \lfloor q \rfloor.$
580 ///
581 /// $f(x, k, \mathrm{Up}) = f(x, y, \mathrm{Ceiling}) = \lceil q \rceil.$
582 ///
583 /// $$
584 /// f(x, k, \mathrm{Nearest}) = \begin{cases}
585 /// \lfloor q \rfloor & \text{if}
586 /// \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\
587 /// \lceil q \rceil & \text{if}
588 /// \\quad q - \lfloor q \rfloor > \frac{1}{2}, \\\\
589 /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor =
590 /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor
591 /// \\ \text{is even}, \\\\
592 /// \lceil q \rceil &
593 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
594 /// \\ \lfloor q \rfloor \\ \text{is odd}.
595 /// \end{cases}
596 /// $$
597 ///
598 /// $f(x, k, \mathrm{Exact}) = q$, but panics if $q \notin \N$.
599 ///
600 /// Then
601 ///
602 /// $f(x, k, r) = (g(x, k, r), \operatorname{cmp}(g(x, k, r), q))$.
603 ///
604 /// # Worst-case complexity
605 /// $T(n, m) = O(n + m)$
606 ///
607 /// $M(n, m) = O(n + m)$
608 ///
609 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and
610 /// $m$ is `max(-bits, 0)`.
611 ///
612 /// # Panics
613 /// Let $k$ be `bits`. Panics if $k$ is positive and `rm` is `Exact` but `self` is not
614 /// divisible by $2^k$.
615 ///
616 /// # Examples
617 /// See [here](super::shr_round#shr_round).
618 #[inline]
619 fn shr_round(mut self, bits: $t, rm: RoundingMode) -> (Natural, Ordering) {
620 let o = self.shr_round_assign(bits, rm);
621 (self, o)
622 }
623 }
624
625 impl<'a> ShrRound<$t> for &Natural {
626 type Output = Natural;
627
628 /// Shifts a [`Natural`] right (divides or multiplies it by a power of 2), taking it by
629 /// reference, and rounds according to the specified rounding mode. An [`Ordering`] is
630 /// also returned, indicating whether the returned value is less than, equal to, or
631 /// greater than the exact value. If `bits` is negative, then the returned [`Ordering`]
632 /// is always `Equal`, even if the higher bits of the result are lost.
633 ///
634 /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether `Exact` can
635 /// be passed, use `self.divisible_by_power_of_2(bits)`.
636 ///
637 /// Let $q = \frac{x}{2^k}$, and let $g$ be the function that just returns the first
638 /// element of the pair, without the [`Ordering`]:
639 ///
640 /// $f(x, k, \mathrm{Down}) = f(x, y, \mathrm{Floor}) = \lfloor q \rfloor.$
641 ///
642 /// $f(x, k, \mathrm{Up}) = f(x, y, \mathrm{Ceiling}) = \lceil q \rceil.$
643 ///
644 /// $$
645 /// f(x, k, \mathrm{Nearest}) = \begin{cases}
646 /// \lfloor q \rfloor & \text{if}
647 /// \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\
648 /// \lceil q \rceil & \text{if}
649 /// \\quad q - \lfloor q \rfloor > \frac{1}{2}, \\\\
650 /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor =
651 /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor
652 /// \\ \text{is even}, \\\\
653 /// \lceil q \rceil &
654 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
655 /// \\ \lfloor q \rfloor \\ \text{is odd}.
656 /// \end{cases}
657 /// $$
658 ///
659 /// $f(x, k, \mathrm{Exact}) = q$, but panics if $q \notin \N$.
660 ///
661 /// Then
662 ///
663 /// $f(x, k, r) = (g(x, k, r), \operatorname{cmp}(g(x, k, r), q))$.
664 ///
665 /// # Worst-case complexity
666 /// $T(n, m) = O(n + m)$
667 ///
668 /// $M(n, m) = O(n + m)$
669 ///
670 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and
671 /// $m$ is `max(-bits, 0)`.
672 ///
673 /// # Worst-case complexity
674 /// $T(n, m) = O(n + m)$
675 ///
676 /// $M(n, m) = O(n + m)$
677 ///
678 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and
679 /// $m$ is `max(-bits, 0)`.
680 ///
681 /// # Panics
682 /// Let $k$ be `bits`. Panics if $k$ is positive and `rm` is `Exact` but `self` is not
683 /// divisible by $2^k$.
684 ///
685 /// # Examples
686 /// See [here](super::shr_round#shr_round).
687 #[inline]
688 fn shr_round(self, bits: $t, rm: RoundingMode) -> (Natural, Ordering) {
689 shr_round_signed_ref_n(self, bits, rm)
690 }
691 }
692
693 impl ShrRoundAssign<$t> for Natural {
694 /// Shifts a [`Natural`] right (divides or multiplies it by a power of 2) and rounds
695 /// according to the specified rounding mode, in place. An [`Ordering`] is returned,
696 /// indicating whether the assigned value is less than, equal to, or greater than the
697 /// exact value. If `bits` is negative, then the returned [`Ordering`] is always
698 /// `Equal`, even if the higher bits of the result are lost.
699 ///
700 /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether `Exact` can
701 /// be passed, use `self.divisible_by_power_of_2(bits)`.
702 ///
703 /// See the [`ShrRound`] documentation for details.
704 ///
705 /// # Worst-case complexity
706 /// $T(n, m) = O(n + m)$
707 ///
708 /// $M(n, m) = O(n + m)$
709 ///
710 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and
711 /// $m$ is `max(-bits, 0)`.
712 ///
713 /// # Panics
714 /// Let $k$ be `bits`. Panics if $k$ is positive and `rm` is `Exact` but `self` is not
715 /// divisible by $2^k$.
716 ///
717 /// # Examples
718 /// See [here](super::shr_round#shr_round_assign).
719 #[inline]
720 fn shr_round_assign(&mut self, bits: $t, rm: RoundingMode) -> Ordering {
721 shr_round_assign_signed_n(self, bits, rm)
722 }
723 }
724 };
725}
726apply_to_signeds!(impl_natural_shr_round_signed);