crypto_bigint/limb/
shr.rs

1//! Limb right bitshift
2
3use crate::{Limb, WrappingShr};
4use core::ops::{Shr, ShrAssign};
5
6impl Limb {
7    /// Computes `self >> shift`.
8    /// Panics if `shift` overflows `Limb::BITS`.
9    #[inline(always)]
10    pub const fn shr(self, shift: u32) -> Self {
11        Limb(self.0 >> shift)
12    }
13
14    /// Computes `self >> 1` and return the result and the carry (0 or `1 << HI_BIT`).
15    #[inline(always)]
16    pub(crate) const fn shr1(self) -> (Self, Self) {
17        (Self(self.0 >> 1), Self(self.0 << Self::HI_BIT))
18    }
19}
20
21macro_rules! impl_shr {
22    ($($shift:ty),+) => {
23        $(
24            impl Shr<$shift> for Limb {
25                type Output = Limb;
26
27                #[inline]
28                fn shr(self, shift: $shift) -> Limb {
29                     Self::shr(self, u32::try_from(shift).expect("invalid shift"))
30                }
31            }
32
33            impl Shr<$shift> for &Limb {
34                type Output = Limb;
35
36                #[inline]
37                fn shr(self, shift: $shift) -> Limb {
38                   *self >> shift
39                }
40            }
41
42            impl ShrAssign<$shift> for Limb {
43                #[inline]
44                fn shr_assign(&mut self, shift: $shift) {
45                    *self = *self >> shift;
46                }
47            }
48        )+
49    };
50}
51
52impl_shr!(i32, u32, usize);
53
54impl WrappingShr for Limb {
55    #[inline]
56    fn wrapping_shr(&self, shift: u32) -> Limb {
57        Self(self.0.wrapping_shr(shift))
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use crate::Limb;
64
65    #[test]
66    fn shr1() {
67        assert_eq!(Limb(2) >> 1, Limb(1));
68    }
69
70    #[test]
71    fn shr2() {
72        assert_eq!(Limb(16) >> 2, Limb(4));
73    }
74
75    #[test]
76    fn shr_assign1() {
77        let mut l = Limb::ONE;
78        l >>= 1;
79        assert_eq!(l, Limb::ZERO);
80    }
81
82    #[test]
83    fn shr_assign2() {
84        let mut l = Limb(32);
85        l >>= 2;
86        assert_eq!(l, Limb(8));
87    }
88}