about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/num/f32.rs62
-rw-r--r--library/core/src/num/f64.rs62
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/num/mod.rs61
-rw-r--r--library/std/src/f32/tests.rs12
-rw-r--r--library/std/src/lib.rs1
6 files changed, 199 insertions, 0 deletions
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 905b0c42458..4571df917f3 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -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.
     ///
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 112a239a145..0ae32c5ea95 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -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.
     ///
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index b9acd0d2990..a56a1dbd17a 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -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)]
diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs
index 37b5e9127d5..4f773a824ef 100644
--- a/library/core/tests/num/mod.rs
+++ b/library/core/tests/num/mod.rs
@@ -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());
diff --git a/library/std/src/f32/tests.rs b/library/std/src/f32/tests.rs
index 0d4b865f339..69fa203ff4e 100644
--- a/library/std/src/f32/tests.rs
+++ b/library/std/src/f32/tests.rs
@@ -20,6 +20,18 @@ fn test_max_nan() {
 }
 
 #[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;
     assert!(nan.is_nan());
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index f2490a77ce0..afd8d8edaa1 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -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)]