ratio operators
This commit is contained in:
parent
617952c1e3
commit
ac250e9d84
@ -1,3 +1,5 @@
|
|||||||
|
use std::ops::Mul;
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Hash)]
|
#[derive(Clone,Copy,Debug,Hash)]
|
||||||
pub struct Ratio<Num,Den>{
|
pub struct Ratio<Num,Den>{
|
||||||
pub(crate)num:Num,
|
pub(crate)num:Num,
|
||||||
@ -8,3 +10,148 @@ impl<Num,Den> Ratio<Num,Den>{
|
|||||||
Self{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