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.
This commit is contained in:
parent
bb39c4925a
commit
eb67f492de
2 changed files with 24 additions and 46 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue