ebi_arithmetic 0.3.13

Exact arithmetic for Ebi - a stochastic process mining utility
Documentation
use malachite::{Integer, Natural, base::num::basic::traits::Zero as MZero, rational::Rational};

use crate::{
    ebi_number::{Signed, Zero},
    exact::is_exact_globally,
    fraction::{
        fraction::EPSILON, fraction_enum::FractionEnum, fraction_exact::FractionExact,
        fraction_f64::FractionF64,
    },
};

impl Zero for FractionF64 {
    fn zero() -> Self {
        Self(0.0)
    }

    fn is_zero(&self) -> bool {
        self.0.is_zero()
    }
}

impl Zero for FractionExact {
    fn zero() -> Self {
        Self(Rational::ZERO.clone())
    }

    fn is_zero(&self) -> bool {
        self.0.is_zero()
    }
}

impl Zero for FractionEnum {
    fn zero() -> Self {
        if is_exact_globally() {
            FractionEnum::Exact(Rational::ZERO)
        } else {
            FractionEnum::Approx(0.0)
        }
    }

    fn is_zero(&self) -> bool {
        match self {
            FractionEnum::Exact(f) => f.is_zero(),
            FractionEnum::Approx(f) => f.is_zero(),
            Self::CannotCombineExactAndApprox => false,
        }
    }

    fn set_zero(&mut self) {
        match self {
            FractionEnum::Exact(f) => *f = Rational::ZERO,
            FractionEnum::Approx(f) => *f = 0.0,
            FractionEnum::CannotCombineExactAndApprox => {}
        }
    }
}

impl Zero for Rational {
    fn zero() -> Self {
        Rational::ZERO.clone()
    }

    fn is_zero(&self) -> bool {
        self == &Rational::ZERO
    }
}

impl Zero for Natural {
    fn zero() -> Self {
        Natural::ZERO.clone()
    }

    fn is_zero(&self) -> bool {
        self == &Natural::ZERO
    }
}

impl Zero for Integer {
    fn zero() -> Self {
        Integer::ZERO.clone()
    }

    fn is_zero(&self) -> bool {
        self == &Integer::ZERO
    }
}

macro_rules! float {
    ($t: ident, $e: expr) => {
        impl Zero for $t {
            fn zero() -> Self {
                0.0
            }

            fn is_zero(&self) -> bool {
                <$t as Signed>::abs(*self) - &$e < 0.0
            }
        }
    };
}

float!(f32, f32::EPSILON);
float!(f64, EPSILON);

macro_rules! ttype {
    ($t:ident) => {
        impl Zero for $t {
            fn zero() -> Self {
                0
            }

            fn is_zero(&self) -> bool {
                *self == 0
            }
        }
    };
}

ttype!(usize);
ttype!(u128);
ttype!(u64);
ttype!(u32);
ttype!(u16);
ttype!(u8);
ttype!(i128);
ttype!(i64);
ttype!(i32);
ttype!(i16);
ttype!(i8);