twibint 0.3.2

Crate for arithmetic on arbitrarily large integers. Provides Python bindings as well.
Documentation
use crate::BigFloat;
use std::iter::Product;
use std::ops::Mul;
use std::ops::MulAssign;

use crate::traits::Digit;

impl<T: Digit> BigFloat<T> {
    #[inline]
    pub(crate) fn set_to_mul(&mut self, a: &BigFloat<T>, b: &BigFloat<T>) {
        self._set_to_mul(
            a.int.sign,
            a.scale,
            &a.int.uint.val,
            b.int.sign,
            b.scale,
            &b.int.uint.val,
        );
    }

    #[inline]
    pub(crate) fn _set_to_mul(
        &mut self,
        a_sign: bool,
        a_scale: isize,
        a: &[T],
        b_sign: bool,
        b_scale: isize,
        b: &[T],
    ) {
        self.int._set_to_mul(a_sign, a, b_sign, b);
        self.scale = a_scale + b_scale;
    }
}

impl<T: Digit> MulAssign<T> for BigFloat<T> {
    fn mul_assign(&mut self, other: T) {
        self.int *= other;
    }
}
impl<T: Digit> MulAssign<&T> for BigFloat<T> {
    fn mul_assign(&mut self, other: &T) {
        *self *= *other;
    }
}
impl<T: Digit> MulAssign<&BigFloat<T>> for BigFloat<T> {
    fn mul_assign(&mut self, other: &BigFloat<T>) {
        *self = &*self * other;
    }
}
impl<T: Digit> MulAssign<BigFloat<T>> for BigFloat<T> {
    fn mul_assign(&mut self, other: BigFloat<T>) {
        *self = &*self * &other;
    }
}
impl<T: Digit> Mul<T> for &BigFloat<T> {
    type Output = BigFloat<T>;
    fn mul(self, other: T) -> BigFloat<T> {
        let mut ret = self.clone();
        ret *= other;
        ret
    }
}
impl<T: Digit> Mul<&T> for &BigFloat<T> {
    type Output = BigFloat<T>;
    fn mul(self, other: &T) -> BigFloat<T> {
        let mut ret = self.clone();
        ret *= other;
        ret
    }
}
impl<T: Digit> Mul<T> for BigFloat<T> {
    type Output = BigFloat<T>;
    fn mul(mut self, other: T) -> BigFloat<T> {
        self *= other;
        self
    }
}
impl<T: Digit> Mul<&T> for BigFloat<T> {
    type Output = BigFloat<T>;
    fn mul(mut self, other: &T) -> BigFloat<T> {
        self *= other;
        self
    }
}

impl<T: Digit> Mul<&BigFloat<T>> for &BigFloat<T> {
    type Output = BigFloat<T>;
    fn mul(self, other: &BigFloat<T>) -> BigFloat<T> {
        let mut ret = BigFloat::default()
            .with_capacity((self.int.uint.val.len() + other.int.uint.val.len()) * T::NB_BITS);
        ret._set_to_mul(
            self.int.sign,
            self.scale,
            &self.int.uint.val,
            other.int.sign,
            other.scale,
            &other.int.uint.val,
        );
        ret.simplify();
        ret
    }
}
impl<T: Digit> Mul<BigFloat<T>> for BigFloat<T> {
    type Output = BigFloat<T>;
    fn mul(self, other: BigFloat<T>) -> BigFloat<T> {
        &self * &other
    }
}
impl<T: Digit> Mul<BigFloat<T>> for &BigFloat<T> {
    type Output = BigFloat<T>;
    fn mul(self, other: BigFloat<T>) -> BigFloat<T> {
        self * &other
    }
}
impl<T: Digit> Mul<&BigFloat<T>> for BigFloat<T> {
    type Output = BigFloat<T>;
    fn mul(self, other: &BigFloat<T>) -> BigFloat<T> {
        &self * other
    }
}

impl<T, D: Digit> Product<T> for BigFloat<D>
where
    BigFloat<D>: MulAssign<T>,
{
    fn product<I>(iter: I) -> BigFloat<D>
    where
        I: Iterator<Item = T>,
    {
        let mut ret = BigFloat::<D>::new(D::ONE);
        for el in iter {
            ret *= el;
        }
        ret
    }
}