twibint 0.3.2

Crate for arithmetic on arbitrarily large integers. Provides Python bindings as well.
Documentation
use std::ops::Shl;
use std::ops::ShlAssign;
use std::ops::Shr;
use std::ops::ShrAssign;

use crate::traits::Digit;
use crate::BigFloat;

impl<T: Digit> BigFloat<T> {
    pub(crate) fn shl(&mut self, b: usize) {
        self.int <<= b % T::NB_BITS;
        let scale_offset: isize = (b / T::NB_BITS).try_into().unwrap();
        self.scale += scale_offset;
    }

    fn shr(&mut self, b: usize) {
        let small_shift = b % T::NB_BITS;
        let big_shift: isize = (b / T::NB_BITS).try_into().unwrap();
        self.scale -= big_shift;

        if (self.int.uint.val[0].trailing_zeros() as usize) < small_shift {
            self.int <<= T::NB_BITS;
            self.scale -= 1;
        }
        self.int >>= small_shift;
    }
}

impl<T: Digit> Shl<usize> for &BigFloat<T> {
    type Output = BigFloat<T>;
    fn shl(self, other: usize) -> BigFloat<T> {
        let mut ret = self.clone();
        ret <<= other;
        ret
    }
}

impl<T: Digit> Shl<usize> for BigFloat<T> {
    type Output = BigFloat<T>;
    fn shl(mut self, other: usize) -> BigFloat<T> {
        self <<= other;
        self
    }
}

impl<T: Digit> ShlAssign<usize> for BigFloat<T> {
    fn shl_assign(&mut self, b: usize) {
        self.shl(b);
        self.simplify();
    }
}

impl<T: Digit> Shr<usize> for &BigFloat<T> {
    type Output = BigFloat<T>;
    fn shr(self, other: usize) -> BigFloat<T> {
        let mut ret = self.clone();
        ret >>= other;
        ret
    }
}

impl<T: Digit> Shr<usize> for BigFloat<T> {
    type Output = BigFloat<T>;
    fn shr(mut self, other: usize) -> BigFloat<T> {
        self >>= other;
        self
    }
}

impl<T: Digit> ShrAssign<usize> for BigFloat<T> {
    fn shr_assign(&mut self, b: usize) {
        self.shr(b)
    }
}