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