ruint/algorithms/
shift.rs

1/// ⚠️ Shift left small.
2#[doc = crate::algorithms::unstable_warning!()]
3#[inline(always)]
4pub fn shift_left_small(limbs: &mut [u64], amount: usize) -> u64 {
5    debug_assert!(amount < 64);
6    let mut overflow = 0;
7    for limb in limbs {
8        let value = (*limb << amount) | overflow;
9        overflow = *limb >> (64 - amount);
10        *limb = value;
11    }
12    overflow
13}
14
15/// ⚠️ Shift right small.
16#[doc = crate::algorithms::unstable_warning!()]
17#[inline(always)]
18pub fn shift_right_small(limbs: &mut [u64], amount: usize) -> u64 {
19    debug_assert!(amount < 64);
20
21    let mut overflow = 0;
22    for limb in limbs.iter_mut().rev() {
23        let value = (*limb >> amount) | overflow;
24        overflow = *limb << (64 - amount);
25        *limb = value;
26    }
27    overflow
28}
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33
34    #[test]
35    fn test_shift_left_small() {
36        let mut limbs = [0x1234_5678_9abc_def0, 0x1234_5678_9abc_def0];
37        let overflow = shift_left_small(&mut limbs, 4);
38        assert_eq!(limbs, [0x2345_6789_abcd_ef00, 0x2345_6789_abcd_ef01]);
39        assert_eq!(overflow, 0x1);
40    }
41
42    #[test]
43    fn test_shift_right_small() {
44        let mut limbs = [0x1234_5678_9abc_deff, 0x1234_5678_9abc_def0];
45        let overflow = shift_right_small(&mut limbs, 4);
46        assert_eq!(limbs, [0x0123_4567_89ab_cdef, 0x0123_4567_89ab_cdef]);
47        assert_eq!(overflow, 0xf << 60);
48    }
49}