@@ -30,7 +30,7 @@ pub type Rational64 = Ratio<i64>;
3030/// Alias for arbitrary precision rationals.
3131pub type BigRational = Ratio < BigInt > ;
3232
33- impl < T : Copy + Num + Ord >
33+ impl < T : Clone + Integer + Ord >
3434 Ratio < T > {
3535 /// Create a ratio representing the integer `t`.
3636 #[ inline( always) ]
@@ -57,53 +57,30 @@ impl<T: Copy + Num + Ord>
5757
5858 /// Put self into lowest terms, with denom > 0.
5959 fn reduce ( & mut self ) {
60- let g : T = gcd ( self . numer , self . denom ) ;
60+ let g : T = self . numer . gcd ( & self . denom ) ;
6161
62- self . numer /= g;
63- self . denom /= g;
62+ // FIXME(#6050): overloaded operators force moves with generic types
63+ // self.numer /= g;
64+ self . numer = self . numer / g;
65+ // FIXME(#6050): overloaded operators force moves with generic types
66+ // self.denom /= g;
67+ self . denom = self . denom / g;
6468
6569 // keep denom positive!
6670 if self . denom < Zero :: zero ( ) {
6771 self . numer = -self . numer ;
6872 self . denom = -self . denom ;
6973 }
7074 }
75+
7176 /// Return a `reduce`d copy of self.
7277 fn reduced ( & self ) -> Ratio < T > {
73- let mut ret = copy * self ;
78+ let mut ret = self . clone ( ) ;
7479 ret. reduce ( ) ;
7580 ret
7681 }
7782}
7883
79- /**
80- Compute the greatest common divisor of two numbers, via Euclid's algorithm.
81-
82- The result can be negative.
83- */
84- #[ inline]
85- pub fn gcd_raw < T : Num > ( n : T , m : T ) -> T {
86- let mut m = m, n = n;
87- while m != Zero :: zero ( ) {
88- let temp = m;
89- m = n % temp;
90- n = temp;
91- }
92- n
93- }
94-
95- /**
96- Compute the greatest common divisor of two numbers, via Euclid's algorithm.
97-
98- The result is always positive.
99- */
100- #[ inline]
101- pub fn gcd < T : Num + Ord > ( n : T , m : T ) -> T {
102- let g = gcd_raw ( n, m) ;
103- if g < Zero :: zero ( ) { -g }
104- else { g }
105- }
106-
10784/* Comparisons */
10885
10986// comparing a/b and c/d is the same as comparing a*d and b*c, so we
@@ -133,7 +110,7 @@ cmp_impl!(impl TotalOrd, cmp -> cmp::Ordering)
133110
134111/* Arithmetic */
135112// a/b * c/d = (a*c)/(b*d)
136- impl < T : Copy + Num + Ord >
113+ impl < T : Clone + Integer + Ord >
137114 Mul < Ratio < T > , Ratio < T > > for Ratio < T > {
138115 #[ inline]
139116 fn mul ( & self , rhs : & Ratio < T > ) -> Ratio < T > {
@@ -142,7 +119,7 @@ impl<T: Copy + Num + Ord>
142119}
143120
144121// (a/b) / (c/d) = (a*d)/(b*c)
145- impl < T : Copy + Num + Ord >
122+ impl < T : Clone + Integer + Ord >
146123 Div < Ratio < T > , Ratio < T > > for Ratio < T > {
147124 #[ inline]
148125 fn div ( & self , rhs : & Ratio < T > ) -> Ratio < T > {
@@ -153,7 +130,7 @@ impl<T: Copy + Num + Ord>
153130// Abstracts the a/b `op` c/d = (a*d `op` b*d) / (b*d) pattern
154131macro_rules! arith_impl {
155132 ( impl $imp: ident, $method: ident) => {
156- impl <T : Copy + Num + Ord >
133+ impl <T : Clone + Integer + Ord >
157134 $imp<Ratio <T >, Ratio <T >> for Ratio <T > {
158135 #[ inline]
159136 fn $method( & self , rhs: & Ratio <T >) -> Ratio <T > {
@@ -173,16 +150,16 @@ arith_impl!(impl Sub, sub)
173150// a/b % c/d = (a*d % b*c)/(b*d)
174151arith_impl ! ( impl Rem , rem)
175152
176- impl < T : Copy + Num + Ord >
153+ impl < T : Clone + Integer + Ord >
177154 Neg < Ratio < T > > for Ratio < T > {
178155 #[ inline]
179156 fn neg ( & self ) -> Ratio < T > {
180- Ratio :: new_raw ( -self . numer , self . denom )
157+ Ratio :: new_raw ( -self . numer , self . denom . clone ( ) )
181158 }
182159}
183160
184161/* Constants */
185- impl < T : Copy + Num + Ord >
162+ impl < T : Clone + Integer + Ord >
186163 Zero for Ratio < T > {
187164 #[ inline]
188165 fn zero ( ) -> Ratio < T > {
@@ -195,19 +172,19 @@ impl<T: Copy + Num + Ord>
195172 }
196173}
197174
198- impl < T : Copy + Num + Ord >
175+ impl < T : Clone + Integer + Ord >
199176 One for Ratio < T > {
200177 #[ inline]
201178 fn one ( ) -> Ratio < T > {
202179 Ratio :: new_raw ( One :: one ( ) , One :: one ( ) )
203180 }
204181}
205182
206- impl < T : Copy + Num + Ord >
183+ impl < T : Clone + Integer + Ord >
207184 Num for Ratio < T > { }
208185
209186/* Utils */
210- impl < T : Copy + Num + Ord >
187+ impl < T : Clone + Integer + Ord >
211188 Round for Ratio < T > {
212189
213190 fn floor ( & self ) -> Ratio < T > {
@@ -241,14 +218,14 @@ impl<T: Copy + Num + Ord>
241218 }
242219
243220 fn fract ( & self ) -> Ratio < T > {
244- Ratio :: new_raw ( self . numer % self . denom , self . denom )
221+ Ratio :: new_raw ( self . numer % self . denom , self . denom . clone ( ) )
245222 }
246223}
247224
248- impl < T : Copy + Num + Ord > Fractional for Ratio < T > {
225+ impl < T : Clone + Integer + Ord > Fractional for Ratio < T > {
249226 #[ inline]
250227 fn recip ( & self ) -> Ratio < T > {
251- Ratio :: new_raw ( self . denom , self . numer )
228+ Ratio :: new_raw ( self . denom . clone ( ) , self . numer . clone ( ) )
252229 }
253230}
254231
@@ -266,7 +243,7 @@ impl<T: ToStrRadix> ToStrRadix for Ratio<T> {
266243 }
267244}
268245
269- impl < T : FromStr + Copy + Num + Ord >
246+ impl < T : FromStr + Clone + Integer + Ord >
270247 FromStr for Ratio < T > {
271248 /// Parses `numer/denom`.
272249 fn from_str ( s : & str ) -> Option < Ratio < T > > {
@@ -276,14 +253,14 @@ impl<T: FromStr + Copy + Num + Ord>
276253 }
277254 } ) ;
278255 if split. len ( ) < 2 { return None ; }
279- do FromStr :: from_str ( split[ 0 ] ) . chain |a| {
280- do FromStr :: from_str ( split[ 1 ] ) . chain |b| {
281- Some ( Ratio :: new ( a, b ) )
256+ do FromStr :: from_str :: < T > ( split[ 0 ] ) . chain |a| {
257+ do FromStr :: from_str :: < T > ( split[ 1 ] ) . chain |b| {
258+ Some ( Ratio :: new ( a. clone ( ) , b . clone ( ) ) )
282259 }
283260 }
284261 }
285262}
286- impl < T : FromStrRadix + Copy + Num + Ord >
263+ impl < T : FromStrRadix + Clone + Integer + Ord >
287264 FromStrRadix for Ratio < T > {
288265 /// Parses `numer/denom` where the numbers are in base `radix`.
289266 fn from_str_radix ( s : & str , radix : uint ) -> Option < Ratio < T > > {
@@ -294,9 +271,9 @@ impl<T: FromStrRadix + Copy + Num + Ord>
294271 } ) ;
295272 if split. len ( ) < 2 { None }
296273 else {
297- do FromStrRadix :: from_str_radix ( split[ 0 ] , radix) . chain |a| {
298- do FromStrRadix :: from_str_radix ( split[ 1 ] , radix) . chain |b| {
299- Some ( Ratio :: new ( a, b ) )
274+ do FromStrRadix :: from_str_radix :: < T > ( split[ 0 ] , radix) . chain |a| {
275+ do FromStrRadix :: from_str_radix :: < T > ( split[ 1 ] , radix) . chain |b| {
276+ Some ( Ratio :: new ( a. clone ( ) , b . clone ( ) ) )
300277 }
301278 }
302279 }
@@ -306,7 +283,7 @@ impl<T: FromStrRadix + Copy + Num + Ord>
306283#[ cfg( test) ]
307284mod test {
308285 use super :: * ;
309- use core:: num:: { Zero , One , FromStrRadix } ;
286+ use core:: num:: { Zero , One , FromStrRadix , IntConvertible } ;
310287 use core:: from_str:: FromStr ;
311288
312289 pub static _0 : Rational = Ratio { numer : 0 , denom : 1 } ;
@@ -316,16 +293,11 @@ mod test {
316293 pub static _3_2: Rational = Ratio { numer : 3 , denom : 2 } ;
317294 pub static _neg1_2: Rational = Ratio { numer : -1 , denom : 2 } ;
318295
319- #[ test]
320- fn test_gcd ( ) {
321- assert_eq ! ( gcd( 10 , 2 ) , 2 ) ;
322- assert_eq ! ( gcd( 10 , 3 ) , 1 ) ;
323- assert_eq ! ( gcd( 0 , 3 ) , 3 ) ;
324- assert_eq ! ( gcd( 3 , 3 ) , 3 ) ;
325-
326- assert_eq ! ( gcd( 3 , -3 ) , 3 ) ;
327- assert_eq ! ( gcd( -6 , 3 ) , 3 ) ;
328- assert_eq ! ( gcd( -4 , -2 ) , 2 ) ;
296+ pub fn to_big ( n : Rational ) -> BigRational {
297+ Ratio :: new (
298+ IntConvertible :: from_int ( n. numer ) ,
299+ IntConvertible :: from_int ( n. denom )
300+ )
329301 }
330302
331303 #[ test]
@@ -374,45 +346,75 @@ mod test {
374346
375347 #[ test]
376348 fn test_add ( ) {
377- assert_eq ! ( _1 + _1_2, _3_2) ;
378- assert_eq ! ( _1 + _1, _2) ;
379- assert_eq ! ( _1_2 + _3_2, _2) ;
380- assert_eq ! ( _1_2 + _neg1_2, _0) ;
349+ fn test ( a : Rational , b : Rational , c : Rational ) {
350+ assert_eq ! ( a + b, c) ;
351+ assert_eq ! ( to_big( a) + to_big( b) , to_big( c) ) ;
352+ }
353+
354+ test ( _1, _1_2, _3_2) ;
355+ test ( _1, _1, _2) ;
356+ test ( _1_2, _3_2, _2) ;
357+ test ( _1_2, _neg1_2, _0) ;
381358 }
382359
383360 #[ test]
384361 fn test_sub ( ) {
385- assert_eq ! ( _1 - _1_2, _1_2) ;
386- assert_eq ! ( _3_2 - _1_2, _1) ;
387- assert_eq ! ( _1 - _neg1_2, _3_2) ;
362+ fn test ( a : Rational , b : Rational , c : Rational ) {
363+ assert_eq ! ( a - b, c) ;
364+ assert_eq ! ( to_big( a) - to_big( b) , to_big( c) )
365+ }
366+
367+ test ( _1, _1_2, _1_2) ;
368+ test ( _3_2, _1_2, _1) ;
369+ test ( _1, _neg1_2, _3_2) ;
388370 }
389371
390372 #[ test]
391373 fn test_mul ( ) {
392- assert_eq ! ( _1 * _1_2, _1_2) ;
393- assert_eq ! ( _1_2 * _3_2, Ratio :: new( 3 , 4 ) ) ;
394- assert_eq ! ( _1_2 * _neg1_2, Ratio :: new( -1 , 4 ) ) ;
374+ fn test ( a : Rational , b : Rational , c : Rational ) {
375+ assert_eq ! ( a * b, c) ;
376+ assert_eq ! ( to_big( a) * to_big( b) , to_big( c) )
377+ }
378+
379+ test ( _1, _1_2, _1_2) ;
380+ test ( _1_2, _3_2, Ratio :: new ( 3 , 4 ) ) ;
381+ test ( _1_2, _neg1_2, Ratio :: new ( -1 , 4 ) ) ;
395382 }
396383
397384 #[ test]
398385 fn test_div ( ) {
399- assert_eq ! ( _1 / _1_2, _2) ;
400- assert_eq ! ( _3_2 / _1_2, _1 + _2) ;
401- assert_eq ! ( _1 / _neg1_2, _neg1_2 + _neg1_2 + _neg1_2 + _neg1_2) ;
386+ fn test ( a : Rational , b : Rational , c : Rational ) {
387+ assert_eq ! ( a / b, c) ;
388+ assert_eq ! ( to_big( a) / to_big( b) , to_big( c) )
389+ }
390+
391+ test ( _1, _1_2, _2) ;
392+ test ( _3_2, _1_2, _1 + _2) ;
393+ test ( _1, _neg1_2, _neg1_2 + _neg1_2 + _neg1_2 + _neg1_2) ;
402394 }
403395
404396 #[ test]
405397 fn test_rem ( ) {
406- assert_eq ! ( _3_2 % _1, _1_2) ;
407- assert_eq ! ( _2 % _neg1_2, _0) ;
408- assert_eq ! ( _1_2 % _2, _1_2) ;
398+ fn test ( a : Rational , b : Rational , c : Rational ) {
399+ assert_eq ! ( a % b, c) ;
400+ assert_eq ! ( to_big( a) % to_big( b) , to_big( c) )
401+ }
402+
403+ test ( _3_2, _1, _1_2) ;
404+ test ( _2, _neg1_2, _0) ;
405+ test ( _1_2, _2, _1_2) ;
409406 }
410407
411408 #[ test]
412409 fn test_neg ( ) {
413- assert_eq ! ( -_0, _0) ;
414- assert_eq ! ( -_1_2, _neg1_2) ;
415- assert_eq ! ( -( -_1) , _1) ;
410+ fn test ( a : Rational , b : Rational ) {
411+ assert_eq ! ( -a, b) ;
412+ assert_eq ! ( -to_big( a) , to_big( b) )
413+ }
414+
415+ test ( _0, _0) ;
416+ test ( _1_2, _neg1_2) ;
417+ test ( -_1, _1) ;
416418 }
417419 #[ test]
418420 fn test_zero ( ) {
0 commit comments