From eb67f492debf2ea7671d3859c42356cf43859de1 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 16 May 2016 14:26:49 +1000 Subject: [PATCH] Deprecate {f32,f64}::abs_sub. The abs_sub name is misleading: the function actually computes the positive difference (`fdim` in C), not the `(x - y).abs()` that *many* people expect from the name. This function can be replaced with just `(x - y).max(0.0)`, mirroring the `abs` version, but this behaves differently with NAN: `NAN.max(0.0) == 0.0`, while `NAN.positive_diff(0.0) == NAN`. People who absolutely need that behaviour can use the C function directly and/or talk to the libs team (we haven't encountered a concrete use-case for this functionality). Closes #30315. --- src/libstd/num/f32.rs | 39 ++++++++++++++------------------------- src/libstd/num/f64.rs | 31 ++++++++++--------------------- 2 files changed, 24 insertions(+), 46 deletions(-) diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 94aa3d6b513ef..c0031aa42e606 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -829,6 +829,13 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[rustc_deprecated(since = "1.10.0", + reason = "you probably meant `(self - other).abs()`: \ + this operation is `(self - other).max(0.0)` (also \ + known as `fdimf` in C). If you truly need the positive \ + difference, consider using that expression or the C function \ + `fdimf`, depending on how you wish to handle NaN (please consider \ + filing an issue describing your use-case too).")] pub fn abs_sub(self, other: f32) -> f32 { unsafe { cmath::fdimf(self, other) } } @@ -939,7 +946,7 @@ impl f32 { /// let f = f32::consts::PI / 2.0; /// /// // asin(sin(pi/2)) - /// let abs_difference = f.sin().asin().abs_sub(f32::consts::PI / 2.0); + /// let abs_difference = (f.sin().asin() - f32::consts::PI / 2.0).abs(); /// /// assert!(abs_difference <= f32::EPSILON); /// ``` @@ -959,7 +966,7 @@ impl f32 { /// let f = f32::consts::PI / 4.0; /// /// // acos(cos(pi/4)) - /// let abs_difference = f.cos().acos().abs_sub(f32::consts::PI / 4.0); + /// let abs_difference = (f.cos().acos() - f32::consts::PI / 4.0).abs(); /// /// assert!(abs_difference <= f32::EPSILON); /// ``` @@ -978,7 +985,7 @@ impl f32 { /// let f = 1.0f32; /// /// // atan(tan(1)) - /// let abs_difference = f.tan().atan().abs_sub(1.0); + /// let abs_difference = (f.tan().atan() - 1.0).abs(); /// /// assert!(abs_difference <= f32::EPSILON); /// ``` @@ -1048,7 +1055,7 @@ impl f32 { /// let x = 7.0f64; /// /// // e^(ln(7)) - 1 - /// let abs_difference = x.ln().exp_m1().abs_sub(6.0); + /// let abs_difference = (x.ln().exp_m1() - 6.0).abs(); /// /// assert!(abs_difference < 1e-10); /// ``` @@ -1108,7 +1115,7 @@ impl f32 { /// let f = x.cosh(); /// // Solving cosh() at 1 gives this result /// let g = (e*e + 1.0)/(2.0*e); - /// let abs_difference = f.abs_sub(g); + /// let abs_difference = (f - g).abs(); /// /// // Same result /// assert!(abs_difference <= f32::EPSILON); @@ -1191,9 +1198,9 @@ impl f32 { /// let e = f32::consts::E; /// let f = e.tanh().atanh(); /// - /// let abs_difference = f.abs_sub(e); + /// let abs_difference = (f - e).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 1e-5); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -1747,24 +1754,6 @@ mod tests { assert!(match nan.frexp() { (x, _) => x.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); - } - - #[test] - fn test_abs_sub_nowin() { - assert!(NAN.abs_sub(-1f32).is_nan()); - assert!(1f32.abs_sub(NAN).is_nan()); - } - #[test] fn test_asinh() { assert_eq!(0.0f32.asinh(), 0.0f32); diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 2beffb64d3dc4..1a46d9a389578 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -718,9 +718,16 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn abs_sub(self, other: f64) -> f64 { - unsafe { cmath::fdim(self, other) } - } + #[rustc_deprecated(since = "1.10.0", + reason = "you probably meant `(self - other).abs()`: \ + this operation is `(self - other).max(0.0)` (also \ + known as `fdim` in C). If you truly need the positive \ + difference, consider using that expression or the C function \ + `fdim`, depending on how you wish to handle NaN (please consider \ + filing an issue describing your use-case too).")] + pub fn abs_sub(self, other: f64) -> f64 { + unsafe { cmath::fdim(self, other) } + } /// Takes the cubic root of a number. /// @@ -1642,24 +1649,6 @@ mod tests { assert!(match nan.frexp() { (x, _) => x.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); - } - - #[test] - fn test_abs_sub_nowin() { - assert!(NAN.abs_sub(-1f64).is_nan()); - assert!(1f64.abs_sub(NAN).is_nan()); - } - #[test] fn test_asinh() { assert_eq!(0.0f64.asinh(), 0.0f64);