diff --git a/ratio_ops/src/ratio.rs b/ratio_ops/src/ratio.rs
index 6ae0ad2..7f806da 100644
--- a/ratio_ops/src/ratio.rs
+++ b/ratio_ops/src/ratio.rs
@@ -1,10 +1,171 @@
 #[derive(Clone,Copy,Debug,Hash)]
 pub struct Ratio<Num,Den>{
-	pub(crate)num:Num,
-	pub(crate)den:Den,
+	pub num:Num,
+	pub den:Den,
 }
 impl<Num,Den> Ratio<Num,Den>{
+	#[inline(always)]
 	pub const fn new(num:Num,den:Den)->Self{
 		Self{num,den}
 	}
 }
+
+impl<Num,Den> Ratio<Num,Den>
+	where
+		Num:core::ops::Div<Den>,
+{
+	#[inline]
+	pub fn divide(num:Num,den:Den)-><Num as core::ops::Div<Den>>::Output{
+		num/den
+	}
+}
+
+//take care to use the ratio methods to avoid nested ratios
+
+impl<LhsNum,LhsDen> Ratio<LhsNum,LhsDen>{
+	#[inline]
+	pub fn mul_ratio<RhsNum,RhsDen>(self,rhs:Ratio<RhsNum,RhsDen>)->Ratio<<LhsNum as core::ops::Mul<RhsNum>>::Output,<LhsDen as core::ops::Mul<RhsDen>>::Output>
+		where
+			LhsNum:core::ops::Mul<RhsNum>,
+			LhsDen:core::ops::Mul<RhsDen>,
+	{
+		Ratio::new(self.num*rhs.num,self.den*rhs.den)
+	}
+	#[inline]
+	pub fn div_ratio<RhsNum,RhsDen>(self,rhs:Ratio<RhsNum,RhsDen>)->Ratio<<LhsNum as core::ops::Mul<RhsDen>>::Output,<LhsDen as core::ops::Mul<RhsNum>>::Output>
+		where
+			LhsNum:core::ops::Mul<RhsDen>,
+			LhsDen:core::ops::Mul<RhsNum>,
+	{
+		Ratio::new(self.num*rhs.den,self.den*rhs.num)
+	}
+}
+macro_rules! impl_ratio_method {
+	($trait:ident, $method:ident, $ratio_method:ident) => {
+		impl<LhsNum,LhsDen> Ratio<LhsNum,LhsDen>{
+			#[inline]
+			pub fn $ratio_method<RhsNum,RhsDen,LhsCrossMul,RhsCrossMul>(self,rhs:Ratio<RhsNum,RhsDen>)->Ratio<<LhsCrossMul as core::ops::$trait<RhsCrossMul>>::Output,<LhsDen as core::ops::Mul<RhsDen>>::Output>
+				where
+					LhsNum:core::ops::Mul<RhsDen,Output=LhsCrossMul>,
+					LhsDen:core::ops::Mul<RhsNum,Output=RhsCrossMul>,
+					LhsDen:core::ops::Mul<RhsDen>,
+					LhsDen:Copy,
+					RhsDen:Copy,
+					LhsCrossMul:core::ops::$trait<RhsCrossMul>,
+			{
+				Ratio::new((self.num*rhs.den).$method(self.den*rhs.num),self.den*rhs.den)
+			}
+		}
+	};
+}
+impl_ratio_method!(Add,add,add_ratio);
+impl_ratio_method!(Sub,sub,sub_ratio);
+impl_ratio_method!(Rem,rem,rem_ratio);
+
+/* generic rhs mul is not possible!
+impl<Lhs,RhsNum,RhsDen> core::ops::Mul<Ratio<RhsNum,RhsDen>> for Lhs
+	where
+		Lhs:core::ops::Mul<RhsNum>,
+{
+	type Output=Ratio<<Lhs as core::ops::Mul<RhsNum>>::Output,RhsDen>;
+	#[inline]
+	fn mul(self,rhs:Ratio<RhsNum,RhsDen>)->Self::Output{
+		Ratio::new(self*rhs.num,rhs.den)
+	}
+}
+*/
+
+//operators
+
+impl<LhsNum,LhsDen> core::ops::Neg for Ratio<LhsNum,LhsDen>
+	where
+		LhsNum:core::ops::Neg,
+{
+	type Output=Ratio<<LhsNum as core::ops::Neg>::Output,LhsDen>;
+	#[inline]
+	fn neg(self)->Self::Output{
+		Ratio::new(-self.num,self.den)
+	}
+}
+impl<LhsNum,LhsDen,Rhs> core::ops::Mul<Rhs> for Ratio<LhsNum,LhsDen>
+	where
+		LhsNum:core::ops::Mul<Rhs>,
+{
+	type Output=Ratio<<LhsNum as core::ops::Mul<Rhs>>::Output,LhsDen>;
+	#[inline]
+	fn mul(self,rhs:Rhs)->Self::Output{
+		Ratio::new(self.num*rhs,self.den)
+	}
+}
+impl<LhsNum,LhsDen,Rhs> core::ops::Div<Rhs> for Ratio<LhsNum,LhsDen>
+	where
+		LhsDen:core::ops::Mul<Rhs>,
+{
+	type Output=Ratio<LhsNum,<LhsDen as core::ops::Mul<Rhs>>::Output>;
+	#[inline]
+	fn div(self,rhs:Rhs)->Self::Output{
+		Ratio::new(self.num,self.den*rhs)
+	}
+}
+
+macro_rules! impl_ratio_operator {
+	($trait:ident, $method:ident) => {
+		impl<LhsNum,LhsDen,Rhs,Intermediate> core::ops::$trait<Rhs> for Ratio<LhsNum,LhsDen>
+			where
+				LhsNum:core::ops::$trait<Intermediate>,
+				LhsDen:Copy,
+				Rhs:core::ops::Mul<LhsDen,Output=Intermediate>,
+		{
+			type Output=Ratio<<LhsNum as core::ops::$trait<Intermediate>>::Output,LhsDen>;
+			#[inline]
+			fn $method(self,rhs:Rhs)->Self::Output{
+				Ratio::new(self.num.$method(rhs*self.den),self.den)
+			}
+		}
+	};
+}
+
+impl_ratio_operator!(Add,add);
+impl_ratio_operator!(Sub,sub);
+impl_ratio_operator!(Rem,rem);
+
+//assign operators
+
+impl<LhsNum,LhsDen,Rhs> core::ops::MulAssign<Rhs> for Ratio<LhsNum,LhsDen>
+	where
+		LhsNum:core::ops::MulAssign<Rhs>,
+{
+	#[inline]
+	fn mul_assign(&mut self,rhs:Rhs){
+		self.num*=rhs;
+	}
+}
+impl<LhsNum,LhsDen,Rhs> core::ops::DivAssign<Rhs> for Ratio<LhsNum,LhsDen>
+	where
+		LhsDen:core::ops::MulAssign<Rhs>,
+{
+	#[inline]
+	fn div_assign(&mut self,rhs:Rhs){
+		self.den*=rhs;
+	}
+}
+
+macro_rules! impl_ratio_assign_operator {
+	($trait:ident, $method:ident) => {
+		impl<LhsNum,LhsDen,Rhs> core::ops::$trait<Rhs> for Ratio<LhsNum,LhsDen>
+			where
+				LhsNum:core::ops::$trait,
+				LhsDen:Copy,
+				Rhs:core::ops::Mul<LhsDen,Output=LhsNum>,
+		{
+			#[inline]
+			fn $method(&mut self,rhs:Rhs){
+				self.num.$method(rhs*self.den)
+			}
+		}
+	};
+}
+
+impl_ratio_assign_operator!(AddAssign,add_assign);
+impl_ratio_assign_operator!(SubAssign,sub_assign);
+impl_ratio_assign_operator!(RemAssign,rem_assign);