num_bigint_dig/algorithms/
shl.rs

1use alloc::borrow::Cow;
2use core::iter::repeat;
3
4use smallvec::SmallVec;
5
6use crate::big_digit::BITS;
7use crate::BigUint;
8
9#[inline]
10pub fn biguint_shl(n: Cow<BigUint>, bits: usize) -> BigUint {
11    let n_unit = bits / BITS;
12    let mut data = match n_unit {
13        0 => n.into_owned().data,
14        _ => {
15            let len = n_unit + n.data.len() + 1;
16            let mut data = SmallVec::with_capacity(len);
17            data.extend(repeat(0).take(n_unit));
18            data.extend(n.data.iter().cloned());
19            data
20        }
21    };
22
23    let n_bits = bits % BITS;
24    if n_bits > 0 {
25        let mut carry = 0;
26        for elem in data[n_unit..].iter_mut() {
27            let new_carry = *elem >> (BITS - n_bits);
28            *elem = (*elem << n_bits) | carry;
29            carry = new_carry;
30        }
31        if carry != 0 {
32            data.push(carry);
33        }
34    }
35
36    BigUint::new_native(data)
37}