diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 05e8b26..7d592d5 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -408,7 +408,12 @@ impl co ratio_ops::ratio::Ratio::new(self,other) } } - +#[cfg(feature="deferred-division")] +impl ratio_ops::ratio::Parity for Fixed{ + fn parity(&self)->bool{ + self.is_negative() + } +} macro_rules! impl_shift_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { impl core::ops::$trait for $struct{ diff --git a/ratio_ops/src/ratio.rs b/ratio_ops/src/ratio.rs index 55732be..b41dc74 100644 --- a/ratio_ops/src/ratio.rs +++ b/ratio_ops/src/ratio.rs @@ -68,17 +68,63 @@ impl_ratio_method!(Add,add,add_ratio); impl_ratio_method!(Sub,sub,sub_ratio); impl_ratio_method!(Rem,rem,rem_ratio); -macro_rules! impl_ratio_ord_method { - ($method:ident, $ratio_method:ident, $output:ty) => { - impl Ratio{ +/// Comparing two ratios needs to know the parity of the denominators +/// For signed integers this can be implemented with is_negative() +pub trait Parity{ + fn parity(&self)->bool; +} +macro_rules! impl_parity_unsigned{ + ($($type:ty),*)=>{ + $( + impl Parity for $type{ + fn parity(&self)->bool{ + false + } + } + )* + }; +} +macro_rules! impl_parity_signed{ + ($($type:ty),*)=>{ + $( + impl Parity for $type{ + fn parity(&self)->bool{ + self.is_negative() + } + } + )* + }; +} +macro_rules! impl_parity_float{ + ($($type:ty),*)=>{ + $( + impl Parity for $type{ + fn parity(&self)->bool{ + self.is_sign_negative() + } + } + )* + }; +} + +impl_parity_unsigned!(u8,u16,u32,u64,u128,usize); +impl_parity_signed!(i8,i16,i32,i64,i128,isize); +impl_parity_float!(f32,f64); + +macro_rules! impl_ratio_ord_method{ + ($method:ident, $ratio_method:ident, $output:ty)=>{ + impl Ratio{ #[inline] - pub fn $ratio_method(self,rhs:Ratio)->$output + pub fn $ratio_method(self,rhs:Ratio)->$output where LhsNum:core::ops::Mul, LhsDen:core::ops::Mul, T:Ord, { - (self.num*rhs.den).$method(&(self.den*rhs.num)) + match self.den.parity()^rhs.den.parity(){ + true=>(self.den*rhs.num).$method(&(self.num*rhs.den)), + false=>(self.num*rhs.den).$method(&(self.den*rhs.num)), + } } } }