fixed_bigint/heapless/
shift.rs1use super::{HeaplessBigInt, zero};
21use crate::MachineWord;
22use const_num_traits::Personality;
23use core::marker::PhantomData;
24use core::ops::{Shl, ShlAssign, Shr, ShrAssign};
25
26impl<T: MachineWord, const CAP: usize, P: Personality> Shl<usize> for HeaplessBigInt<T, CAP, P> {
27 type Output = Self;
28
29 fn shl(self, bits: usize) -> Self::Output {
30 let word_bits = core::mem::size_of::<T>() * 8;
31 let word_shift = bits / word_bits;
32 let bit_shift = bits % word_bits;
33
34 let out_len = self.len as usize;
36 let mut limbs = [zero::<T>(); CAP];
37
38 let mut i = 0;
39 while i < out_len {
40 let dst_lo = i + word_shift;
41 if dst_lo < out_len {
42 let lo = self.limbs[i] << bit_shift;
43 limbs[dst_lo] |= lo;
44 if bit_shift > 0 {
45 let dst_hi = dst_lo + 1;
46 if dst_hi < out_len {
47 let hi = self.limbs[i] >> (word_bits - bit_shift);
48 limbs[dst_hi] |= hi;
49 }
50 }
51 }
52 i += 1;
53 }
54
55 Self {
56 limbs,
57 len: out_len as u16,
58 _p: PhantomData,
59 }
60 }
61}
62
63impl<T: MachineWord, const CAP: usize, P: Personality> ShlAssign<usize>
64 for HeaplessBigInt<T, CAP, P>
65{
66 fn shl_assign(&mut self, bits: usize) {
67 *self = *self << bits;
68 }
69}
70
71impl<T: MachineWord, const CAP: usize, P: Personality> ShrAssign<usize>
72 for HeaplessBigInt<T, CAP, P>
73{
74 fn shr_assign(&mut self, bits: usize) {
75 *self = *self >> bits;
76 }
77}
78
79impl<T: MachineWord, const CAP: usize, P: Personality> Shr<usize> for HeaplessBigInt<T, CAP, P> {
80 type Output = Self;
81
82 fn shr(self, bits: usize) -> Self::Output {
83 let word_bits = core::mem::size_of::<T>() * 8;
84 let word_shift = bits / word_bits;
85 let bit_shift = bits % word_bits;
86
87 let mut limbs = [zero::<T>(); CAP];
88 if word_shift >= self.len as usize {
89 return Self {
90 limbs,
91 len: 0,
92 _p: PhantomData,
93 };
94 }
95
96 let out_len = self.len as usize - word_shift;
97
98 let mut i = 0;
99 while i < out_len {
100 let src_lo = i + word_shift;
101 let lo = self.limbs[src_lo] >> bit_shift;
102 let hi = if bit_shift > 0 && src_lo + 1 < self.len as usize {
103 self.limbs[src_lo + 1] << (word_bits - bit_shift)
104 } else {
105 zero::<T>()
106 };
107 limbs[i] = lo | hi;
108 i += 1;
109 }
110
111 Self {
112 limbs,
113 len: out_len as u16,
114 _p: PhantomData,
115 }
116 }
117}