diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 580a612aebb4..bdd11200419f 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -312,6 +312,13 @@ impl Signed for f32 { #[inline(always)] 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 /// @@ -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 41fc9cca66e5..7c6246757cd8 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -325,6 +325,13 @@ impl Signed for f64 { #[inline(always)] 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 /// @@ -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 95f3a76b8008..35e113094876 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -734,6 +734,15 @@ impl Signed for float { #[inline(always)] 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 /// @@ -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 95c187a7be22..06a9a0b45627 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -264,6 +264,15 @@ impl Signed for T { if self.is_negative() { -*self } else { *self } } + /// + /// 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 /// @@ -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 2496ba497dcc..7a71729e3e73 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 { 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 cd347098e251..a5cf929ed93a 100644 --- a/src/libstd/num/bigint.rs +++ b/src/libstd/num/bigint.rs @@ -831,6 +831,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 { @@ -1920,6 +1925,15 @@ mod bigint_tests { check(11, 5, 55); } + #[test] + fn test_abs_sub() { + assert_eq!((-One::one::()).abs_sub(&One::one()), Zero::zero()); + assert_eq!(One::one::().abs_sub(&One::one()), Zero::zero()); + assert_eq!(One::one::().abs_sub(&Zero::zero()), One::one()); + assert_eq!(One::one::().abs_sub(&-One::one::()), + IntConvertible::from_int(2)); + } + #[test] fn test_to_str_radix() { fn check(n: int, ans: &str) {