Skip to content

Commit a9ac2b9

Browse files
committed
Add abs_sub method to Signed trait
1 parent 314b485 commit a9ac2b9

File tree

6 files changed

+140
-5
lines changed

6 files changed

+140
-5
lines changed

src/libcore/num/f32.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,13 @@ impl Signed for f32 {
312312
#[inline(always)]
313313
fn abs(&self) -> f32 { abs(*self) }
314314

315+
///
316+
/// The positive difference of two numbers. Returns `0.0` if the number is less than or
317+
/// equal to `other`, otherwise the difference between`self` and `other` is returned.
318+
///
319+
#[inline(always)]
320+
fn abs_sub(&self, other: &f32) -> f32 { abs_sub(*self, *other) }
321+
315322
///
316323
/// # Returns
317324
///
@@ -959,7 +966,7 @@ mod tests {
959966
}
960967

961968
#[test]
962-
pub fn test_signed() {
969+
pub fn test_abs() {
963970
assert_eq!(infinity.abs(), infinity);
964971
assert_eq!(1f32.abs(), 1f32);
965972
assert_eq!(0f32.abs(), 0f32);
@@ -968,7 +975,24 @@ mod tests {
968975
assert_eq!(neg_infinity.abs(), infinity);
969976
assert_eq!((1f32/neg_infinity).abs(), 0f32);
970977
assert!(NaN.abs().is_NaN());
978+
}
971979

980+
#[test]
981+
fn test_abs_sub() {
982+
assert_eq!((-1f32).abs_sub(&1f32), 0f32);
983+
assert_eq!(1f32.abs_sub(&1f32), 0f32);
984+
assert_eq!(1f32.abs_sub(&0f32), 1f32);
985+
assert_eq!(1f32.abs_sub(&-1f32), 2f32);
986+
assert_eq!(neg_infinity.abs_sub(&0f32), 0f32);
987+
assert_eq!(infinity.abs_sub(&1f32), infinity);
988+
assert_eq!(0f32.abs_sub(&neg_infinity), infinity);
989+
assert_eq!(0f32.abs_sub(&infinity), 0f32);
990+
assert!(NaN.abs_sub(&-1f32).is_NaN());
991+
assert!(1f32.abs_sub(&NaN).is_NaN());
992+
}
993+
994+
#[test]
995+
fn test_signum() {
972996
assert_eq!(infinity.signum(), 1f32);
973997
assert_eq!(1f32.signum(), 1f32);
974998
assert_eq!(0f32.signum(), 1f32);
@@ -977,7 +1001,10 @@ mod tests {
9771001
assert_eq!(neg_infinity.signum(), -1f32);
9781002
assert_eq!((1f32/neg_infinity).signum(), -1f32);
9791003
assert!(NaN.signum().is_NaN());
1004+
}
9801005

1006+
#[test]
1007+
fn test_is_positive() {
9811008
assert!(infinity.is_positive());
9821009
assert!(1f32.is_positive());
9831010
assert!(0f32.is_positive());
@@ -986,7 +1013,10 @@ mod tests {
9861013
assert!(!neg_infinity.is_positive());
9871014
assert!(!(1f32/neg_infinity).is_positive());
9881015
assert!(!NaN.is_positive());
1016+
}
9891017

1018+
#[test]
1019+
fn test_is_negative() {
9901020
assert!(!infinity.is_negative());
9911021
assert!(!1f32.is_negative());
9921022
assert!(!0f32.is_negative());

src/libcore/num/f64.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,13 @@ impl Signed for f64 {
325325
#[inline(always)]
326326
fn abs(&self) -> f64 { abs(*self) }
327327

328+
///
329+
/// The positive difference of two numbers. Returns `0.0` if the number is less than or
330+
/// equal to `other`, otherwise the difference between`self` and `other` is returned.
331+
///
332+
#[inline(always)]
333+
fn abs_sub(&self, other: &f64) -> f64 { abs_sub(*self, *other) }
334+
328335
///
329336
/// # Returns
330337
///
@@ -594,6 +601,7 @@ impl Float for f64 {
594601
#[inline(always)]
595602
fn neg_zero() -> f64 { -0.0 }
596603

604+
/// Returns `true` if the number is NaN
597605
#[inline(always)]
598606
fn is_NaN(&self) -> bool { *self != *self }
599607

@@ -603,7 +611,7 @@ impl Float for f64 {
603611
*self == Float::infinity() || *self == Float::neg_infinity()
604612
}
605613

606-
/// Returns `true` if the number is finite
614+
/// Returns `true` if the number is not infinite or NaN
607615
#[inline(always)]
608616
fn is_finite(&self) -> bool {
609617
!(self.is_NaN() || self.is_infinite())
@@ -1005,7 +1013,7 @@ mod tests {
10051013
}
10061014

10071015
#[test]
1008-
pub fn test_signed() {
1016+
pub fn test_abs() {
10091017
assert_eq!(infinity.abs(), infinity);
10101018
assert_eq!(1f64.abs(), 1f64);
10111019
assert_eq!(0f64.abs(), 0f64);
@@ -1014,7 +1022,24 @@ mod tests {
10141022
assert_eq!(neg_infinity.abs(), infinity);
10151023
assert_eq!((1f64/neg_infinity).abs(), 0f64);
10161024
assert!(NaN.abs().is_NaN());
1025+
}
10171026

1027+
#[test]
1028+
fn test_abs_sub() {
1029+
assert_eq!((-1f64).abs_sub(&1f64), 0f64);
1030+
assert_eq!(1f64.abs_sub(&1f64), 0f64);
1031+
assert_eq!(1f64.abs_sub(&0f64), 1f64);
1032+
assert_eq!(1f64.abs_sub(&-1f64), 2f64);
1033+
assert_eq!(neg_infinity.abs_sub(&0f64), 0f64);
1034+
assert_eq!(infinity.abs_sub(&1f64), infinity);
1035+
assert_eq!(0f64.abs_sub(&neg_infinity), infinity);
1036+
assert_eq!(0f64.abs_sub(&infinity), 0f64);
1037+
assert!(NaN.abs_sub(&-1f64).is_NaN());
1038+
assert!(1f64.abs_sub(&NaN).is_NaN());
1039+
}
1040+
1041+
#[test]
1042+
fn test_signum() {
10181043
assert_eq!(infinity.signum(), 1f64);
10191044
assert_eq!(1f64.signum(), 1f64);
10201045
assert_eq!(0f64.signum(), 1f64);
@@ -1023,7 +1048,10 @@ mod tests {
10231048
assert_eq!(neg_infinity.signum(), -1f64);
10241049
assert_eq!((1f64/neg_infinity).signum(), -1f64);
10251050
assert!(NaN.signum().is_NaN());
1051+
}
10261052

1053+
#[test]
1054+
fn test_is_positive() {
10271055
assert!(infinity.is_positive());
10281056
assert!(1f64.is_positive());
10291057
assert!(0f64.is_positive());
@@ -1032,7 +1060,10 @@ mod tests {
10321060
assert!(!neg_infinity.is_positive());
10331061
assert!(!(1f64/neg_infinity).is_positive());
10341062
assert!(!NaN.is_positive());
1063+
}
10351064

1065+
#[test]
1066+
fn test_is_negative() {
10361067
assert!(!infinity.is_negative());
10371068
assert!(!1f64.is_negative());
10381069
assert!(!0f64.is_negative());

src/libcore/num/float.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,15 @@ impl Signed for float {
734734
#[inline(always)]
735735
fn abs(&self) -> float { abs(*self) }
736736
737+
///
738+
/// The positive difference of two numbers. Returns `0.0` if the number is less than or
739+
/// equal to `other`, otherwise the difference between`self` and `other` is returned.
740+
///
741+
#[inline(always)]
742+
fn abs_sub(&self, other: &float) -> float {
743+
(*self as f64).abs_sub(&(*other as f64)) as float
744+
}
745+
737746
///
738747
/// # Returns
739748
///
@@ -978,7 +987,7 @@ mod tests {
978987
}
979988
980989
#[test]
981-
fn test_signed() {
990+
fn test_abs() {
982991
assert_eq!(infinity.abs(), infinity);
983992
assert_eq!(1f.abs(), 1f);
984993
assert_eq!(0f.abs(), 0f);
@@ -987,7 +996,24 @@ mod tests {
987996
assert_eq!(neg_infinity.abs(), infinity);
988997
assert_eq!((1f/neg_infinity).abs(), 0f);
989998
assert!(NaN.abs().is_NaN());
999+
}
1000+
1001+
#[test]
1002+
fn test_abs_sub() {
1003+
assert_eq!((-1f).abs_sub(&1f), 0f);
1004+
assert_eq!(1f.abs_sub(&1f), 0f);
1005+
assert_eq!(1f.abs_sub(&0f), 1f);
1006+
assert_eq!(1f.abs_sub(&-1f), 2f);
1007+
assert_eq!(neg_infinity.abs_sub(&0f), 0f);
1008+
assert_eq!(infinity.abs_sub(&1f), infinity);
1009+
assert_eq!(0f.abs_sub(&neg_infinity), infinity);
1010+
assert_eq!(0f.abs_sub(&infinity), 0f);
1011+
assert!(NaN.abs_sub(&-1f).is_NaN());
1012+
assert!(1f.abs_sub(&NaN).is_NaN());
1013+
}
9901014
1015+
#[test]
1016+
fn test_signum() {
9911017
assert_eq!(infinity.signum(), 1f);
9921018
assert_eq!(1f.signum(), 1f);
9931019
assert_eq!(0f.signum(), 1f);
@@ -996,7 +1022,10 @@ mod tests {
9961022
assert_eq!(neg_infinity.signum(), -1f);
9971023
assert_eq!((1f/neg_infinity).signum(), -1f);
9981024
assert!(NaN.signum().is_NaN());
1025+
}
9991026
1027+
#[test]
1028+
fn test_is_positive() {
10001029
assert!(infinity.is_positive());
10011030
assert!(1f.is_positive());
10021031
assert!(0f.is_positive());
@@ -1005,7 +1034,10 @@ mod tests {
10051034
assert!(!neg_infinity.is_positive());
10061035
assert!(!(1f/neg_infinity).is_positive());
10071036
assert!(!NaN.is_positive());
1037+
}
10081038
1039+
#[test]
1040+
fn test_is_negative() {
10091041
assert!(!infinity.is_negative());
10101042
assert!(!1f.is_negative());
10111043
assert!(!0f.is_negative());

src/libcore/num/int-template.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,15 @@ impl Signed for T {
264264
if self.is_negative() { -*self } else { *self }
265265
}
266266
267+
///
268+
/// The positive difference of two numbers. Returns `0` if the number is less than or
269+
/// equal to `other`, otherwise the difference between`self` and `other` is returned.
270+
///
271+
#[inline(always)]
272+
fn abs_sub(&self, other: &T) -> T {
273+
if *self <= *other { 0 } else { *self - *other }
274+
}
275+
267276
///
268277
/// # Returns
269278
///
@@ -554,21 +563,38 @@ mod tests {
554563
}
555564
556565
#[test]
557-
pub fn test_signed() {
566+
pub fn test_abs() {
558567
assert_eq!((1 as T).abs(), 1 as T);
559568
assert_eq!((0 as T).abs(), 0 as T);
560569
assert_eq!((-1 as T).abs(), 1 as T);
570+
}
571+
572+
#[test]
573+
fn test_abs_sub() {
574+
assert_eq!((-1 as T).abs_sub(&(1 as T)), 0 as T);
575+
assert_eq!((1 as T).abs_sub(&(1 as T)), 0 as T);
576+
assert_eq!((1 as T).abs_sub(&(0 as T)), 1 as T);
577+
assert_eq!((1 as T).abs_sub(&(-1 as T)), 2 as T);
578+
}
561579
580+
#[test]
581+
fn test_signum() {
562582
assert_eq!((1 as T).signum(), 1 as T);
563583
assert_eq!((0 as T).signum(), 0 as T);
564584
assert_eq!((-0 as T).signum(), 0 as T);
565585
assert_eq!((-1 as T).signum(), -1 as T);
586+
}
566587
588+
#[test]
589+
fn test_is_positive() {
567590
assert!((1 as T).is_positive());
568591
assert!(!(0 as T).is_positive());
569592
assert!(!(-0 as T).is_positive());
570593
assert!(!(-1 as T).is_positive());
594+
}
571595
596+
#[test]
597+
fn test_is_negative() {
572598
assert!(!(1 as T).is_negative());
573599
assert!(!(0 as T).is_negative());
574600
assert!(!(-0 as T).is_negative());

src/libcore/num/num.rs

+2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ pub trait One {
5555
pub trait Signed: Num
5656
+ Neg<Self> {
5757
fn abs(&self) -> Self;
58+
fn abs_sub(&self, other: &Self) -> Self;
5859
fn signum(&self) -> Self;
60+
5961
fn is_positive(&self) -> bool;
6062
fn is_negative(&self) -> bool;
6163
}

src/libstd/num/bigint.rs

+14
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,11 @@ impl Signed for BigInt {
831831
}
832832
}
833833

834+
#[inline(always)]
835+
fn abs_sub(&self, other: &BigInt) -> BigInt {
836+
if *self <= *other { Zero::zero() } else { *self - *other }
837+
}
838+
834839
#[inline(always)]
835840
fn signum(&self) -> BigInt {
836841
match self.sign {
@@ -1920,6 +1925,15 @@ mod bigint_tests {
19201925
check(11, 5, 55);
19211926
}
19221927
1928+
#[test]
1929+
fn test_abs_sub() {
1930+
assert_eq!((-One::one::<BigInt>()).abs_sub(&One::one()), Zero::zero());
1931+
assert_eq!(One::one::<BigInt>().abs_sub(&One::one()), Zero::zero());
1932+
assert_eq!(One::one::<BigInt>().abs_sub(&Zero::zero()), One::one());
1933+
assert_eq!(One::one::<BigInt>().abs_sub(&-One::one::<BigInt>()),
1934+
IntConvertible::from_int(2));
1935+
}
1936+
19231937
#[test]
19241938
fn test_to_str_radix() {
19251939
fn check(n: int, ans: &str) {

0 commit comments

Comments
 (0)