about summary refs log tree commit diff
path: root/library/core/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-11-21 10:19:33 +0000
committerbors <bors@rust-lang.org>2021-11-21 10:19:33 +0000
commit3bfde2f1f4fc9409ecb63dfe1370df66171cf861 (patch)
treeed9e0b4780c7980749b09d4fd1ea9b57202c709a /library/core/src
parentb8e5ab20ed7a7677a998a163ccf7853764b195e6 (diff)
parenta54eae94a019a4128265413f3799b8d93a81c2e3 (diff)
downloadrust-3bfde2f1f4fc9409ecb63dfe1370df66171cf861.tar.gz
rust-3bfde2f1f4fc9409ecb63dfe1370df66171cf861.zip
Auto merge of #91104 - matthiaskrgr:rollup-duk33o1, r=matthiaskrgr
Rollup of 4 pull requests

Successful merges:

 - #91008 (Adds IEEE 754-2019 minimun and maximum functions for f32/f64)
 - #91070 (Make `LLVMRustGetOrInsertGlobal` always return a `GlobalVariable`)
 - #91097 (Add spaces in opaque `impl Trait` with more than one trait)
 - #91098 (Don't suggest certain fixups (`.field`, `.await`, etc) when reporting errors while matching on arrays )

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'library/core/src')
-rw-r--r--library/core/src/num/f32.rs68
-rw-r--r--library/core/src/num/f64.rs68
2 files changed, 136 insertions, 0 deletions
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 905b0c42458..c4a232ef36c 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -673,6 +673,9 @@ impl f32 {
 
     /// Returns the maximum of the two numbers.
     ///
+    /// Follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs.
+    /// This matches the behavior of libm’s fmin.
+    ///
     /// ```
     /// let x = 1.0f32;
     /// let y = 2.0f32;
@@ -689,6 +692,9 @@ impl f32 {
 
     /// Returns the minimum of the two numbers.
     ///
+    /// Follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs.
+    /// This matches the behavior of libm’s fmin.
+    ///
     /// ```
     /// let x = 1.0f32;
     /// let y = 2.0f32;
@@ -703,6 +709,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 follows 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 follows 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..85ee6aa2cb8 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -689,6 +689,9 @@ impl f64 {
 
     /// Returns the maximum of the two numbers.
     ///
+    /// Follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs.
+    /// This matches the behavior of libm’s fmin.
+    ///
     /// ```
     /// let x = 1.0_f64;
     /// let y = 2.0_f64;
@@ -705,6 +708,9 @@ impl f64 {
 
     /// Returns the minimum of the two numbers.
     ///
+    /// Follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs.
+    /// This matches the behavior of libm’s fmin.
+    ///
     /// ```
     /// let x = 1.0_f64;
     /// let y = 2.0_f64;
@@ -719,6 +725,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 follows 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 follows 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.
     ///