[types] Implement Add for Frac
This commit is contained in:
		
							parent
							
								
									a5ed11ea77
								
							
						
					
					
						commit
						5aca4cfbe4
					
				
					 2 changed files with 39 additions and 11 deletions
				
			
		|  | @ -5,13 +5,13 @@ | |||
| use std::any::Any; | ||||
| use std::fmt; | ||||
| use std::ops::{Add, Mul}; | ||||
| use number::arith::GCD; | ||||
| use number::arith::{GCD, LCM}; | ||||
| use number::{Int, Number}; | ||||
| use object::{Obj, Object}; | ||||
| 
 | ||||
| /// A fraction consisting of a numerator and denominator.
 | ||||
| #[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] | ||||
| pub struct Frac(Int, Int); | ||||
| #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] | ||||
| pub struct Frac { p: Int, q: Int } | ||||
| 
 | ||||
| impl Frac { | ||||
|     pub fn new(p: Int, q: Int) -> Result<Frac, ()> { | ||||
|  | @ -19,31 +19,59 @@ impl Frac { | |||
|             // TODO: Return a more specific error about dividing by zero.
 | ||||
|             Err(()) | ||||
|         } else { | ||||
|             Ok(Frac(p, q).reduced()) | ||||
|             Ok(Frac{p, q}.reduced()) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn reduced(self) -> Frac { | ||||
|         let gcd = self.0.gcd(self.1); | ||||
|         Frac(self.0 / gcd, self.1 / gcd) | ||||
|         let gcd = self.p.gcd(self.q); | ||||
|         Frac { p: self.p / gcd, q: self.q / gcd } | ||||
|     } | ||||
| 
 | ||||
|     fn _add(self, rhs: Frac) -> Frac { | ||||
|         let lcm = self.q.lcm(rhs.q); | ||||
|         let p = self.p * lcm + rhs.p * lcm; | ||||
|         let q = self.q * lcm; | ||||
|         Frac::new(p, q).unwrap() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Number for Frac { | ||||
|     fn as_int(&self) -> Option<Int> { | ||||
|         if self.1 == Int(1) { | ||||
|             Some(self.0) | ||||
|         if self.q == Int(1) { | ||||
|             Some(self.p) | ||||
|         } else { | ||||
|             None | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn as_frac(&self) -> Option<Frac> { Frac::new(self.0, self.1).ok() } | ||||
|     fn as_frac(&self) -> Option<Frac> { Frac::new(self.p, self.q).ok() } | ||||
| } | ||||
| 
 | ||||
| impl Add for Frac { | ||||
|     type Output = Frac; | ||||
|     fn add(self, rhs: Self) -> Self::Output { | ||||
|         self._add(rhs) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a> Add<Frac> for &'a Frac { | ||||
|     type Output = Frac; | ||||
|     fn add(self, rhs: Frac) -> Self::Output { | ||||
|         self._add(rhs) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'b> Add<&'a Frac> for &'b Frac { | ||||
|     type Output = Frac; | ||||
|     fn add(self, rhs: &Frac) -> Self::Output { | ||||
|         self._add(*rhs) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl fmt::Display for Frac { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         write!(f, "{}/{}", self.0, self.1) | ||||
|         write!(f, "{}/{}", self.p, self.q) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -62,7 +62,7 @@ impl<'a, 'b> Div<&'a Int> for &'b Int { | |||
| 
 | ||||
| impl GCD for Int { | ||||
|     fn gcd(self, other: Int) -> Int { | ||||
| 		let (mut a, mut b) = if self.0 > other.0 { | ||||
| 		let (mut a, mut b) = if self > other { | ||||
| 			(self.0, other.0) | ||||
| 		} else { | ||||
| 			(other.0, self.0) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue