@@ -15,6 +15,7 @@ use Integer;
1515use std:: cmp;
1616use std:: fmt;
1717use std:: from_str:: FromStr ;
18+ use std:: num;
1819use std:: num:: { Zero , One , ToStrRadix , FromStrRadix } ;
1920use bigint:: { BigInt , BigUint , Sign , Plus , Minus } ;
2021
@@ -273,6 +274,36 @@ impl<T: Clone + Integer + PartialOrd>
273274impl < T : Clone + Integer + PartialOrd >
274275 Num for Ratio < T > { }
275276
277+ impl < T : Clone + Integer + PartialOrd >
278+ num:: Signed for Ratio < T > {
279+ #[ inline]
280+ fn abs ( & self ) -> Ratio < T > {
281+ if self . is_negative ( ) { -self . clone ( ) } else { self . clone ( ) }
282+ }
283+
284+ #[ inline]
285+ fn abs_sub ( & self , other : & Ratio < T > ) -> Ratio < T > {
286+ if * self <= * other { Zero :: zero ( ) } else { * self - * other }
287+ }
288+
289+ #[ inline]
290+ fn signum ( & self ) -> Ratio < T > {
291+ if * self > Zero :: zero ( ) {
292+ num:: one ( )
293+ } else if self . is_zero ( ) {
294+ num:: zero ( )
295+ } else {
296+ - num:: one :: < Ratio < T > > ( )
297+ }
298+ }
299+
300+ #[ inline]
301+ fn is_positive ( & self ) -> bool { * self > Zero :: zero ( ) }
302+
303+ #[ inline]
304+ fn is_negative ( & self ) -> bool { * self < Zero :: zero ( ) }
305+ }
306+
276307/* String conversions */
277308impl < T : fmt:: Show + Eq + One > fmt:: Show for Ratio < T > {
278309 /// Renders as `numer/denom`. If denom=1, renders as numer.
@@ -338,6 +369,7 @@ mod test {
338369 use super :: { Ratio , Rational , BigRational } ;
339370 use std:: num:: { Zero , One , FromStrRadix , FromPrimitive , ToStrRadix } ;
340371 use std:: from_str:: FromStr ;
372+ use std:: num;
341373
342374 pub static _0 : Rational = Ratio { numer : 0 , denom : 1 } ;
343375 pub static _1 : Rational = Ratio { numer : 1 , denom : 1 } ;
@@ -672,4 +704,16 @@ mod test {
672704 assert_eq ! ( Ratio :: from_float( f64 :: INFINITY ) , None ) ;
673705 assert_eq ! ( Ratio :: from_float( f64 :: NEG_INFINITY ) , None ) ;
674706 }
707+
708+ #[ test]
709+ fn test_signed ( ) {
710+ assert_eq ! ( _neg1_2. abs( ) , _1_2) ;
711+ assert_eq ! ( _3_2. abs_sub( & _1_2) , _1) ;
712+ assert_eq ! ( _1_2. abs_sub( & _3_2) , Zero :: zero( ) ) ;
713+ assert_eq ! ( _1_2. signum( ) , One :: one( ) ) ;
714+ assert_eq ! ( _neg1_2. signum( ) , - num:: one:: <Ratio <int>>( ) ) ;
715+ assert ! ( _neg1_2. is_negative( ) ) ;
716+ assert ! ( ! _neg1_2. is_positive( ) ) ;
717+ assert ! ( ! _1_2. is_negative( ) ) ;
718+ }
675719}
0 commit comments