@@ -15,6 +15,7 @@ use Integer;
15
15
use std:: cmp;
16
16
use std:: fmt;
17
17
use std:: from_str:: FromStr ;
18
+ use std:: num;
18
19
use std:: num:: { Zero , One , ToStrRadix , FromStrRadix } ;
19
20
use bigint:: { BigInt , BigUint , Sign , Plus , Minus } ;
20
21
@@ -273,6 +274,36 @@ impl<T: Clone + Integer + PartialOrd>
273
274
impl < T : Clone + Integer + PartialOrd >
274
275
Num for Ratio < T > { }
275
276
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
+
276
307
/* String conversions */
277
308
impl < T : fmt:: Show + Eq + One > fmt:: Show for Ratio < T > {
278
309
/// Renders as `numer/denom`. If denom=1, renders as numer.
@@ -338,6 +369,7 @@ mod test {
338
369
use super :: { Ratio , Rational , BigRational } ;
339
370
use std:: num:: { Zero , One , FromStrRadix , FromPrimitive , ToStrRadix } ;
340
371
use std:: from_str:: FromStr ;
372
+ use std:: num;
341
373
342
374
pub static _0 : Rational = Ratio { numer : 0 , denom : 1 } ;
343
375
pub static _1 : Rational = Ratio { numer : 1 , denom : 1 } ;
@@ -672,4 +704,16 @@ mod test {
672
704
assert_eq ! ( Ratio :: from_float( f64 :: INFINITY ) , None ) ;
673
705
assert_eq ! ( Ratio :: from_float( f64 :: NEG_INFINITY ) , None ) ;
674
706
}
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
+ }
675
719
}
0 commit comments