about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrendan Zabarauskas <bjzaba@yahoo.com.au>2013-05-07 14:36:32 +1000
committerBrendan Zabarauskas <bjzaba@yahoo.com.au>2013-05-07 19:16:03 +1000
commita9ac2b95f485c31e40273dee7f09dcfff8340777 (patch)
tree1df12ee707e16ff8cda02af66ea929cc51ccfc15
parent314b485c9c480c4a7f47c28716e629d642e2d412 (diff)
downloadrust-a9ac2b95f485c31e40273dee7f09dcfff8340777.tar.gz
rust-a9ac2b95f485c31e40273dee7f09dcfff8340777.zip
Add abs_sub method to Signed trait
-rw-r--r--src/libcore/num/f32.rs32
-rw-r--r--src/libcore/num/f64.rs35
-rw-r--r--src/libcore/num/float.rs34
-rw-r--r--src/libcore/num/int-template.rs28
-rw-r--r--src/libcore/num/num.rs2
-rw-r--r--src/libstd/num/bigint.rs14
6 files changed, 140 insertions, 5 deletions
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 580a612aebb..bdd11200419 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -313,6 +313,13 @@ impl Signed for f32 {
     fn abs(&self) -> f32 { abs(*self) }
 
     ///
+    /// The positive difference of two numbers. Returns `0.0` if the number is less than or
+    /// equal to `other`, otherwise the difference between`self` and `other` is returned.
+    ///
+    #[inline(always)]
+    fn abs_sub(&self, other: &f32) -> f32 { abs_sub(*self, *other) }
+
+    ///
     /// # Returns
     ///
     /// - `1.0` if the number is positive, `+0.0` or `infinity`
@@ -959,7 +966,7 @@ mod tests {
     }
 
     #[test]
-    pub fn test_signed() {
+    pub fn test_abs() {
         assert_eq!(infinity.abs(), infinity);
         assert_eq!(1f32.abs(), 1f32);
         assert_eq!(0f32.abs(), 0f32);
@@ -968,7 +975,24 @@ mod tests {
         assert_eq!(neg_infinity.abs(), infinity);
         assert_eq!((1f32/neg_infinity).abs(), 0f32);
         assert!(NaN.abs().is_NaN());
+    }
 
+    #[test]
+    fn test_abs_sub() {
+        assert_eq!((-1f32).abs_sub(&1f32), 0f32);
+        assert_eq!(1f32.abs_sub(&1f32), 0f32);
+        assert_eq!(1f32.abs_sub(&0f32), 1f32);
+        assert_eq!(1f32.abs_sub(&-1f32), 2f32);
+        assert_eq!(neg_infinity.abs_sub(&0f32), 0f32);
+        assert_eq!(infinity.abs_sub(&1f32), infinity);
+        assert_eq!(0f32.abs_sub(&neg_infinity), infinity);
+        assert_eq!(0f32.abs_sub(&infinity), 0f32);
+        assert!(NaN.abs_sub(&-1f32).is_NaN());
+        assert!(1f32.abs_sub(&NaN).is_NaN());
+    }
+
+    #[test]
+    fn test_signum() {
         assert_eq!(infinity.signum(), 1f32);
         assert_eq!(1f32.signum(), 1f32);
         assert_eq!(0f32.signum(), 1f32);
@@ -977,7 +1001,10 @@ mod tests {
         assert_eq!(neg_infinity.signum(), -1f32);
         assert_eq!((1f32/neg_infinity).signum(), -1f32);
         assert!(NaN.signum().is_NaN());
+    }
 
+    #[test]
+    fn test_is_positive() {
         assert!(infinity.is_positive());
         assert!(1f32.is_positive());
         assert!(0f32.is_positive());
@@ -986,7 +1013,10 @@ mod tests {
         assert!(!neg_infinity.is_positive());
         assert!(!(1f32/neg_infinity).is_positive());
         assert!(!NaN.is_positive());
+    }
 
+    #[test]
+    fn test_is_negative() {
         assert!(!infinity.is_negative());
         assert!(!1f32.is_negative());
         assert!(!0f32.is_negative());
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 41fc9cca66e..7c6246757cd 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -326,6 +326,13 @@ impl Signed for f64 {
     fn abs(&self) -> f64 { abs(*self) }
 
     ///
+    /// The positive difference of two numbers. Returns `0.0` if the number is less than or
+    /// equal to `other`, otherwise the difference between`self` and `other` is returned.
+    ///
+    #[inline(always)]
+    fn abs_sub(&self, other: &f64) -> f64 { abs_sub(*self, *other) }
+
+    ///
     /// # Returns
     ///
     /// - `1.0` if the number is positive, `+0.0` or `infinity`
@@ -594,6 +601,7 @@ impl Float for f64 {
     #[inline(always)]
     fn neg_zero() -> f64 { -0.0 }
 
+    /// Returns `true` if the number is NaN
     #[inline(always)]
     fn is_NaN(&self) -> bool { *self != *self }
 
@@ -603,7 +611,7 @@ impl Float for f64 {
         *self == Float::infinity() || *self == Float::neg_infinity()
     }
 
-    /// Returns `true` if the number is finite
+    /// Returns `true` if the number is not infinite or NaN
     #[inline(always)]
     fn is_finite(&self) -> bool {
         !(self.is_NaN() || self.is_infinite())
@@ -1005,7 +1013,7 @@ mod tests {
     }
 
     #[test]
-    pub fn test_signed() {
+    pub fn test_abs() {
         assert_eq!(infinity.abs(), infinity);
         assert_eq!(1f64.abs(), 1f64);
         assert_eq!(0f64.abs(), 0f64);
@@ -1014,7 +1022,24 @@ mod tests {
         assert_eq!(neg_infinity.abs(), infinity);
         assert_eq!((1f64/neg_infinity).abs(), 0f64);
         assert!(NaN.abs().is_NaN());
+    }
 
+    #[test]
+    fn test_abs_sub() {
+        assert_eq!((-1f64).abs_sub(&1f64), 0f64);
+        assert_eq!(1f64.abs_sub(&1f64), 0f64);
+        assert_eq!(1f64.abs_sub(&0f64), 1f64);
+        assert_eq!(1f64.abs_sub(&-1f64), 2f64);
+        assert_eq!(neg_infinity.abs_sub(&0f64), 0f64);
+        assert_eq!(infinity.abs_sub(&1f64), infinity);
+        assert_eq!(0f64.abs_sub(&neg_infinity), infinity);
+        assert_eq!(0f64.abs_sub(&infinity), 0f64);
+        assert!(NaN.abs_sub(&-1f64).is_NaN());
+        assert!(1f64.abs_sub(&NaN).is_NaN());
+    }
+
+    #[test]
+    fn test_signum() {
         assert_eq!(infinity.signum(), 1f64);
         assert_eq!(1f64.signum(), 1f64);
         assert_eq!(0f64.signum(), 1f64);
@@ -1023,7 +1048,10 @@ mod tests {
         assert_eq!(neg_infinity.signum(), -1f64);
         assert_eq!((1f64/neg_infinity).signum(), -1f64);
         assert!(NaN.signum().is_NaN());
+    }
 
+    #[test]
+    fn test_is_positive() {
         assert!(infinity.is_positive());
         assert!(1f64.is_positive());
         assert!(0f64.is_positive());
@@ -1032,7 +1060,10 @@ mod tests {
         assert!(!neg_infinity.is_positive());
         assert!(!(1f64/neg_infinity).is_positive());
         assert!(!NaN.is_positive());
+    }
 
+    #[test]
+    fn test_is_negative() {
         assert!(!infinity.is_negative());
         assert!(!1f64.is_negative());
         assert!(!0f64.is_negative());
diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs
index 95f3a76b800..35e11309487 100644
--- a/src/libcore/num/float.rs
+++ b/src/libcore/num/float.rs
@@ -735,6 +735,15 @@ impl Signed for float {
     fn abs(&self) -> float { abs(*self) }
 
     ///
+    /// The positive difference of two numbers. Returns `0.0` if the number is less than or
+    /// equal to `other`, otherwise the difference between`self` and `other` is returned.
+    ///
+    #[inline(always)]
+    fn abs_sub(&self, other: &float) -> float {
+        (*self as f64).abs_sub(&(*other as f64)) as float
+    }
+
+    ///
     /// # Returns
     ///
     /// - `1.0` if the number is positive, `+0.0` or `infinity`
@@ -978,7 +987,7 @@ mod tests {
     }
 
     #[test]
-    fn test_signed() {
+    fn test_abs() {
         assert_eq!(infinity.abs(), infinity);
         assert_eq!(1f.abs(), 1f);
         assert_eq!(0f.abs(), 0f);
@@ -987,7 +996,24 @@ mod tests {
         assert_eq!(neg_infinity.abs(), infinity);
         assert_eq!((1f/neg_infinity).abs(), 0f);
         assert!(NaN.abs().is_NaN());
+    }
+
+    #[test]
+    fn test_abs_sub() {
+        assert_eq!((-1f).abs_sub(&1f), 0f);
+        assert_eq!(1f.abs_sub(&1f), 0f);
+        assert_eq!(1f.abs_sub(&0f), 1f);
+        assert_eq!(1f.abs_sub(&-1f), 2f);
+        assert_eq!(neg_infinity.abs_sub(&0f), 0f);
+        assert_eq!(infinity.abs_sub(&1f), infinity);
+        assert_eq!(0f.abs_sub(&neg_infinity), infinity);
+        assert_eq!(0f.abs_sub(&infinity), 0f);
+        assert!(NaN.abs_sub(&-1f).is_NaN());
+        assert!(1f.abs_sub(&NaN).is_NaN());
+    }
 
+    #[test]
+    fn test_signum() {
         assert_eq!(infinity.signum(), 1f);
         assert_eq!(1f.signum(), 1f);
         assert_eq!(0f.signum(), 1f);
@@ -996,7 +1022,10 @@ mod tests {
         assert_eq!(neg_infinity.signum(), -1f);
         assert_eq!((1f/neg_infinity).signum(), -1f);
         assert!(NaN.signum().is_NaN());
+    }
 
+    #[test]
+    fn test_is_positive() {
         assert!(infinity.is_positive());
         assert!(1f.is_positive());
         assert!(0f.is_positive());
@@ -1005,7 +1034,10 @@ mod tests {
         assert!(!neg_infinity.is_positive());
         assert!(!(1f/neg_infinity).is_positive());
         assert!(!NaN.is_positive());
+    }
 
+    #[test]
+    fn test_is_negative() {
         assert!(!infinity.is_negative());
         assert!(!1f.is_negative());
         assert!(!0f.is_negative());
diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs
index 95c187a7be2..06a9a0b4562 100644
--- a/src/libcore/num/int-template.rs
+++ b/src/libcore/num/int-template.rs
@@ -265,6 +265,15 @@ impl Signed for T {
     }
 
     ///
+    /// The positive difference of two numbers. Returns `0` if the number is less than or
+    /// equal to `other`, otherwise the difference between`self` and `other` is returned.
+    ///
+    #[inline(always)]
+    fn abs_sub(&self, other: &T) -> T {
+        if *self <= *other { 0 } else { *self - *other }
+    }
+
+    ///
     /// # Returns
     ///
     /// - `0` if the number is zero
@@ -554,21 +563,38 @@ mod tests {
     }
 
     #[test]
-    pub fn test_signed() {
+    pub fn test_abs() {
         assert_eq!((1 as T).abs(), 1 as T);
         assert_eq!((0 as T).abs(), 0 as T);
         assert_eq!((-1 as T).abs(), 1 as T);
+    }
+
+    #[test]
+    fn test_abs_sub() {
+        assert_eq!((-1 as T).abs_sub(&(1 as T)), 0 as T);
+        assert_eq!((1 as T).abs_sub(&(1 as T)), 0 as T);
+        assert_eq!((1 as T).abs_sub(&(0 as T)), 1 as T);
+        assert_eq!((1 as T).abs_sub(&(-1 as T)), 2 as T);
+    }
 
+    #[test]
+    fn test_signum() {
         assert_eq!((1 as T).signum(), 1 as T);
         assert_eq!((0 as T).signum(), 0 as T);
         assert_eq!((-0 as T).signum(), 0 as T);
         assert_eq!((-1 as T).signum(), -1 as T);
+    }
 
+    #[test]
+    fn test_is_positive() {
         assert!((1 as T).is_positive());
         assert!(!(0 as T).is_positive());
         assert!(!(-0 as T).is_positive());
         assert!(!(-1 as T).is_positive());
+    }
 
+    #[test]
+    fn test_is_negative() {
         assert!(!(1 as T).is_negative());
         assert!(!(0 as T).is_negative());
         assert!(!(-0 as T).is_negative());
diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs
index 2496ba497dc..7a71729e3e7 100644
--- a/src/libcore/num/num.rs
+++ b/src/libcore/num/num.rs
@@ -55,7 +55,9 @@ pub trait One {
 pub trait Signed: Num
                 + Neg<Self> {
     fn abs(&self) -> Self;
+    fn abs_sub(&self, other: &Self) -> Self;
     fn signum(&self) -> Self;
+
     fn is_positive(&self) -> bool;
     fn is_negative(&self) -> bool;
 }
diff --git a/src/libstd/num/bigint.rs b/src/libstd/num/bigint.rs
index cd347098e25..a5cf929ed93 100644
--- a/src/libstd/num/bigint.rs
+++ b/src/libstd/num/bigint.rs
@@ -832,6 +832,11 @@ impl Signed for BigInt {
     }
 
     #[inline(always)]
+    fn abs_sub(&self, other: &BigInt) -> BigInt {
+        if *self <= *other { Zero::zero() } else { *self - *other }
+    }
+
+    #[inline(always)]
     fn signum(&self) -> BigInt {
         match self.sign {
             Plus  => BigInt::from_biguint(Plus, One::one()),
@@ -1921,6 +1926,15 @@ mod bigint_tests {
     }
 
     #[test]
+    fn test_abs_sub() {
+        assert_eq!((-One::one::<BigInt>()).abs_sub(&One::one()), Zero::zero());
+        assert_eq!(One::one::<BigInt>().abs_sub(&One::one()), Zero::zero());
+        assert_eq!(One::one::<BigInt>().abs_sub(&Zero::zero()), One::one());
+        assert_eq!(One::one::<BigInt>().abs_sub(&-One::one::<BigInt>()),
+                   IntConvertible::from_int(2));
+    }
+
+    #[test]
     fn test_to_str_radix() {
         fn check(n: int, ans: &str) {
             assert!(ans == IntConvertible::from_int::<BigInt>(n).to_str_radix(10));