mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Implement IEEE 754-2019 minimun and maximum functions for f32/f64
This commit is contained in:
parent
41301c3b23
commit
a8ee0e9c2c
@ -703,6 +703,68 @@ impl f32 {
|
||||
intrinsics::minnumf32(self, other)
|
||||
}
|
||||
|
||||
/// Returns the maximum of the two numbers, propagating NaNs.
|
||||
///
|
||||
/// This returns NaN when *either* argument is NaN, as opposed to
|
||||
/// [`f32::max`] which only returns NaN when *both* arguments are NaN.
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(float_minimum_maximum)]
|
||||
/// let x = 1.0f32;
|
||||
/// let y = 2.0f32;
|
||||
///
|
||||
/// assert_eq!(x.maximum(y), y);
|
||||
/// assert!(x.maximum(f32::NAN).is_nan());
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the greater
|
||||
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
|
||||
/// Note that this follow the semantics specified in IEEE 754-2019.
|
||||
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
|
||||
#[inline]
|
||||
pub fn maximum(self, other: f32) -> f32 {
|
||||
if self > other {
|
||||
self
|
||||
} else if other > self {
|
||||
other
|
||||
} else if self == other {
|
||||
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
|
||||
} else {
|
||||
self + other
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the minimum of the two numbers, propagating NaNs.
|
||||
///
|
||||
/// This returns NaN when *either* argument is NaN, as opposed to
|
||||
/// [`f32::min`] which only returns NaN when *both* arguments are NaN.
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(float_minimum_maximum)]
|
||||
/// let x = 1.0f32;
|
||||
/// let y = 2.0f32;
|
||||
///
|
||||
/// assert_eq!(x.minimum(y), x);
|
||||
/// assert!(x.minimum(f32::NAN).is_nan());
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the lesser
|
||||
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
|
||||
/// Note that this follow the semantics specified in IEEE 754-2019.
|
||||
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
|
||||
#[inline]
|
||||
pub fn minimum(self, other: f32) -> f32 {
|
||||
if self < other {
|
||||
self
|
||||
} else if other < self {
|
||||
other
|
||||
} else if self == other {
|
||||
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
|
||||
} else {
|
||||
self + other
|
||||
}
|
||||
}
|
||||
|
||||
/// Rounds toward zero and converts to any primitive integer type,
|
||||
/// assuming that the value is finite and fits in that type.
|
||||
///
|
||||
|
@ -719,6 +719,68 @@ impl f64 {
|
||||
intrinsics::minnumf64(self, other)
|
||||
}
|
||||
|
||||
/// Returns the maximum of the two numbers, propagating NaNs.
|
||||
///
|
||||
/// This returns NaN when *either* argument is NaN, as opposed to
|
||||
/// [`f64::max`] which only returns NaN when *both* arguments are NaN.
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(float_minimum_maximum)]
|
||||
/// let x = 1.0_f64;
|
||||
/// let y = 2.0_f64;
|
||||
///
|
||||
/// assert_eq!(x.maximum(y), y);
|
||||
/// assert!(x.maximum(f64::NAN).is_nan());
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the greater
|
||||
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
|
||||
/// Note that this follow the semantics specified in IEEE 754-2019.
|
||||
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
|
||||
#[inline]
|
||||
pub fn maximum(self, other: f64) -> f64 {
|
||||
if self > other {
|
||||
self
|
||||
} else if other > self {
|
||||
other
|
||||
} else if self == other {
|
||||
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
|
||||
} else {
|
||||
self + other
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the minimum of the two numbers, propagating NaNs.
|
||||
///
|
||||
/// This returns NaN when *either* argument is NaN, as opposed to
|
||||
/// [`f64::min`] which only returns NaN when *both* arguments are NaN.
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(float_minimum_maximum)]
|
||||
/// let x = 1.0_f64;
|
||||
/// let y = 2.0_f64;
|
||||
///
|
||||
/// assert_eq!(x.minimum(y), x);
|
||||
/// assert!(x.minimum(f64::NAN).is_nan());
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the lesser
|
||||
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
|
||||
/// Note that this follow the semantics specified in IEEE 754-2019.
|
||||
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
|
||||
#[inline]
|
||||
pub fn minimum(self, other: f64) -> f64 {
|
||||
if self < other {
|
||||
self
|
||||
} else if other < self {
|
||||
other
|
||||
} else if self == other {
|
||||
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
|
||||
} else {
|
||||
self + other
|
||||
}
|
||||
}
|
||||
|
||||
/// Rounds toward zero and converts to any primitive integer type,
|
||||
/// assuming that the value is finite and fits in that type.
|
||||
///
|
||||
|
@ -27,6 +27,7 @@
|
||||
#![feature(extern_types)]
|
||||
#![feature(flt2dec)]
|
||||
#![feature(fmt_internals)]
|
||||
#![feature(float_minimum_maximum)]
|
||||
#![feature(array_from_fn)]
|
||||
#![feature(hashmap_internals)]
|
||||
#![feature(try_find)]
|
||||
|
@ -715,6 +715,67 @@ macro_rules! test_float {
|
||||
assert!(($nan as $fty).max($nan).is_nan());
|
||||
}
|
||||
#[test]
|
||||
fn minimum() {
|
||||
assert_eq!((0.0 as $fty).minimum(0.0), 0.0);
|
||||
assert!((0.0 as $fty).minimum(0.0).is_sign_positive());
|
||||
assert_eq!((-0.0 as $fty).minimum(0.0), -0.0);
|
||||
assert!((-0.0 as $fty).minimum(0.0).is_sign_negative());
|
||||
assert_eq!((-0.0 as $fty).minimum(-0.0), -0.0);
|
||||
assert!((-0.0 as $fty).minimum(-0.0).is_sign_negative());
|
||||
assert_eq!((9.0 as $fty).minimum(9.0), 9.0);
|
||||
assert_eq!((-9.0 as $fty).minimum(0.0), -9.0);
|
||||
assert_eq!((0.0 as $fty).minimum(9.0), 0.0);
|
||||
assert!((0.0 as $fty).minimum(9.0).is_sign_positive());
|
||||
assert_eq!((-0.0 as $fty).minimum(9.0), -0.0);
|
||||
assert!((-0.0 as $fty).minimum(9.0).is_sign_negative());
|
||||
assert_eq!((-0.0 as $fty).minimum(-9.0), -9.0);
|
||||
assert_eq!(($inf as $fty).minimum(9.0), 9.0);
|
||||
assert_eq!((9.0 as $fty).minimum($inf), 9.0);
|
||||
assert_eq!(($inf as $fty).minimum(-9.0), -9.0);
|
||||
assert_eq!((-9.0 as $fty).minimum($inf), -9.0);
|
||||
assert_eq!(($neginf as $fty).minimum(9.0), $neginf);
|
||||
assert_eq!((9.0 as $fty).minimum($neginf), $neginf);
|
||||
assert_eq!(($neginf as $fty).minimum(-9.0), $neginf);
|
||||
assert_eq!((-9.0 as $fty).minimum($neginf), $neginf);
|
||||
assert!(($nan as $fty).minimum(9.0).is_nan());
|
||||
assert!(($nan as $fty).minimum(-9.0).is_nan());
|
||||
assert!((9.0 as $fty).minimum($nan).is_nan());
|
||||
assert!((-9.0 as $fty).minimum($nan).is_nan());
|
||||
assert!(($nan as $fty).minimum($nan).is_nan());
|
||||
}
|
||||
#[test]
|
||||
fn maximum() {
|
||||
assert_eq!((0.0 as $fty).maximum(0.0), 0.0);
|
||||
assert!((0.0 as $fty).maximum(0.0).is_sign_positive());
|
||||
assert_eq!((-0.0 as $fty).maximum(0.0), 0.0);
|
||||
assert!((-0.0 as $fty).maximum(0.0).is_sign_positive());
|
||||
assert_eq!((-0.0 as $fty).maximum(-0.0), -0.0);
|
||||
assert!((-0.0 as $fty).maximum(-0.0).is_sign_negative());
|
||||
assert_eq!((9.0 as $fty).maximum(9.0), 9.0);
|
||||
assert_eq!((-9.0 as $fty).maximum(0.0), 0.0);
|
||||
assert!((-9.0 as $fty).maximum(0.0).is_sign_positive());
|
||||
assert_eq!((-9.0 as $fty).maximum(-0.0), -0.0);
|
||||
assert!((-9.0 as $fty).maximum(-0.0).is_sign_negative());
|
||||
assert_eq!((0.0 as $fty).maximum(9.0), 9.0);
|
||||
assert_eq!((0.0 as $fty).maximum(-9.0), 0.0);
|
||||
assert!((0.0 as $fty).maximum(-9.0).is_sign_positive());
|
||||
assert_eq!((-0.0 as $fty).maximum(-9.0), -0.0);
|
||||
assert!((-0.0 as $fty).maximum(-9.0).is_sign_negative());
|
||||
assert_eq!(($inf as $fty).maximum(9.0), $inf);
|
||||
assert_eq!((9.0 as $fty).maximum($inf), $inf);
|
||||
assert_eq!(($inf as $fty).maximum(-9.0), $inf);
|
||||
assert_eq!((-9.0 as $fty).maximum($inf), $inf);
|
||||
assert_eq!(($neginf as $fty).maximum(9.0), 9.0);
|
||||
assert_eq!((9.0 as $fty).maximum($neginf), 9.0);
|
||||
assert_eq!(($neginf as $fty).maximum(-9.0), -9.0);
|
||||
assert_eq!((-9.0 as $fty).maximum($neginf), -9.0);
|
||||
assert!(($nan as $fty).maximum(9.0).is_nan());
|
||||
assert!(($nan as $fty).maximum(-9.0).is_nan());
|
||||
assert!((9.0 as $fty).maximum($nan).is_nan());
|
||||
assert!((-9.0 as $fty).maximum($nan).is_nan());
|
||||
assert!(($nan as $fty).maximum($nan).is_nan());
|
||||
}
|
||||
#[test]
|
||||
fn rem_euclid() {
|
||||
let a: $fty = 42.0;
|
||||
assert!($inf.rem_euclid(a).is_nan());
|
||||
|
@ -19,6 +19,18 @@ fn test_max_nan() {
|
||||
assert_eq!(2.0f32.max(f32::NAN), 2.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_minimum() {
|
||||
assert!(f32::NAN.minimum(2.0).is_nan());
|
||||
assert!(2.0f32.minimum(f32::NAN).is_nan());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_maximum() {
|
||||
assert!(f32::NAN.maximum(2.0).is_nan());
|
||||
assert!(2.0f32.maximum(f32::NAN).is_nan());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nan() {
|
||||
let nan: f32 = f32::NAN;
|
||||
|
@ -287,6 +287,7 @@
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(extend_one)]
|
||||
#![feature(fn_traits)]
|
||||
#![feature(float_minimum_maximum)]
|
||||
#![feature(format_args_nl)]
|
||||
#![feature(gen_future)]
|
||||
#![feature(generator_trait)]
|
||||
|
Loading…
Reference in New Issue
Block a user