ratio operators
This commit is contained in:
parent
617952c1e3
commit
ac250e9d84
@ -1,3 +1,5 @@
|
||||
use std::ops::Mul;
|
||||
|
||||
#[derive(Clone,Copy,Debug,Hash)]
|
||||
pub struct Ratio<Num,Den>{
|
||||
pub(crate)num:Num,
|
||||
@ -8,3 +10,148 @@ impl<Num,Den> Ratio<Num,Den>{
|
||||
Self{num,den}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Num,Den,Rhs> PartialEq<Rhs> for Ratio<Num,Den>
|
||||
where
|
||||
Den:Copy,
|
||||
Rhs:Mul<Den>+Copy,
|
||||
Num:PartialEq<<Rhs as Mul<Den>>::Output>
|
||||
{
|
||||
fn eq(&self,rhs:&Rhs)->bool{
|
||||
self.num.eq(&rhs.mul(self.den))
|
||||
}
|
||||
}
|
||||
/*
|
||||
//You can't do Ratio==Ratio I guess
|
||||
impl<Num,Den> Eq for Ratio<Num,Den>
|
||||
where
|
||||
Num:Mul<Den>,
|
||||
<Num as Mul<Den>>::Output:PartialEq
|
||||
{}
|
||||
*/
|
||||
|
||||
// num/den == rhs
|
||||
// num == rhs * den
|
||||
|
||||
impl<Num,Den,Rhs> PartialOrd<Rhs> for Ratio<Num,Den>
|
||||
where
|
||||
Den:Copy,
|
||||
Rhs:Mul<Den>+Copy,
|
||||
Num:PartialOrd<<Rhs as Mul<Den>>::Output>
|
||||
{
|
||||
fn partial_cmp(&self,rhs:&Rhs)->Option<std::cmp::Ordering>{
|
||||
self.num.partial_cmp(&rhs.mul(self.den))
|
||||
}
|
||||
}
|
||||
/*
|
||||
impl<Den,Rhs> Ord for Ratio<<Rhs as Mul<Den>>::Output,Den>
|
||||
where
|
||||
Rhs:Mul<Den>,
|
||||
Rhs:Ord,
|
||||
<Rhs as Mul<Den>>::Output:Ord,
|
||||
{
|
||||
fn cmp(&self,other:&Rhs)->std::cmp::Ordering{
|
||||
self.num.cmp(&other.mul(self.den))
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl<NewNum,Num:std::ops::Neg<Output=NewNum>,Den> std::ops::Neg for Ratio<Num,Den>{
|
||||
type Output=Ratio<NewNum,Den>;
|
||||
fn neg(self)->Self::Output{
|
||||
Ratio{
|
||||
num:self.num.neg(),
|
||||
den:self.den,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// num/den + rhs == new_num/den
|
||||
// new_num = num + rhs * den
|
||||
|
||||
macro_rules! impl_operator {
|
||||
($struct:ident,$trait:ident,$method:ident)=>{
|
||||
impl<Num,Den,Rhs> core::ops::$trait<Rhs> for $struct<Num,Den>
|
||||
where
|
||||
Den:Copy,
|
||||
Rhs:Mul<Den>,
|
||||
Num:core::ops::$trait<<Rhs as Mul<Den>>::Output>,
|
||||
{
|
||||
type Output=$struct<<Num as core::ops::$trait<<Rhs as Mul<Den>>::Output>>::Output,Den>;
|
||||
|
||||
fn $method(self,rhs:Rhs)->Self::Output{
|
||||
$struct{
|
||||
num:self.num.$method(rhs.mul(self.den)),
|
||||
den:self.den,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! impl_assign_operator{
|
||||
($struct:ident,$trait:ident,$method:ident)=>{
|
||||
impl<Num,Den,Rhs> core::ops::$trait<Rhs> for $struct<Num,Den>
|
||||
where
|
||||
Den:Copy,
|
||||
Rhs:Mul<Den>,
|
||||
Num:core::ops::$trait<<Rhs as Mul<Den>>::Output>,
|
||||
{
|
||||
fn $method(&mut self,rhs:Rhs){
|
||||
self.num.$method(rhs.mul(self.den));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Impl arithmetic operators
|
||||
impl_assign_operator!(Ratio,AddAssign,add_assign);
|
||||
impl_operator!(Ratio,Add,add);
|
||||
impl_assign_operator!(Ratio,SubAssign,sub_assign);
|
||||
impl_operator!(Ratio,Sub,sub);
|
||||
// num/den % rhs == new_num/den
|
||||
// new_num = num % (rhs * den)
|
||||
impl_assign_operator!(Ratio,RemAssign,rem_assign);
|
||||
impl_operator!(Ratio,Rem,rem);
|
||||
|
||||
//mul and div is special
|
||||
impl<Num,Den,Rhs> Mul<Rhs> for Ratio<Num,Den>
|
||||
where
|
||||
Num:Mul<Rhs>,
|
||||
{
|
||||
type Output=Ratio<<Num as Mul<Rhs>>::Output,Den>;
|
||||
fn mul(self,rhs:Rhs)->Self::Output{
|
||||
Ratio{
|
||||
num:self.num.mul(rhs),
|
||||
den:self.den,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<Num,Den,Rhs> core::ops::MulAssign<Rhs> for Ratio<Num,Den>
|
||||
where
|
||||
Num:core::ops::MulAssign<Rhs>,
|
||||
{
|
||||
fn mul_assign(&mut self,rhs:Rhs){
|
||||
self.num.mul_assign(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Num,Den,Rhs> core::ops::Div<Rhs> for Ratio<Num,Den>
|
||||
where
|
||||
Den:Mul<Rhs>,
|
||||
{
|
||||
type Output=Ratio<Num,<Den as Mul<Rhs>>::Output>;
|
||||
fn div(self,rhs:Rhs)->Self::Output{
|
||||
Ratio{
|
||||
num:self.num,
|
||||
den:self.den.mul(rhs),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<Num,Den,Rhs> core::ops::DivAssign<Rhs> for Ratio<Num,Den>
|
||||
where
|
||||
Den:core::ops::MulAssign<Rhs>,
|
||||
{
|
||||
fn div_assign(&mut self,rhs:Rhs){
|
||||
self.den.mul_assign(rhs);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user