From 77610afe09b65fd2ff8215d3e0e461af3dc47fdc Mon Sep 17 00:00:00 2001 From: Chen-Pang He Date: Sun, 12 May 2024 05:09:15 +0800 Subject: [PATCH 1/2] Implement NaN propagating minmax with TotalOrder and FloatCore --- src/float.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/float.rs b/src/float.rs index d0d21a5..bb1e9ce 100644 --- a/src/float.rs +++ b/src/float.rs @@ -2245,7 +2245,7 @@ float_const_impl! { /// Trait for floating point numbers that provide an implementation /// of the `totalOrder` predicate as defined in the IEEE 754 (2008 revision) /// floating point standard. -pub trait TotalOrder { +pub trait TotalOrder: FloatCore { /// Return the ordering between `self` and `other`. /// /// Unlike the standard partial comparison between floating point numbers, @@ -2297,6 +2297,32 @@ pub trait TotalOrder { /// check_lt(-0.0_f64, 0.0_f64); /// ``` fn total_cmp(&self, other: &Self) -> Ordering; + + /// Get the maximum of two numbers, propagating NaN + /// + /// For this operation, -0.0 is considered to be less than +0.0 as + /// specified in IEEE 754-2019. + #[must_use] + fn maximum(self, other: Self) -> Self { + match (self.is_nan(), other.is_nan()) { + (true, _) => self, + (_, true) => other, + _ => core::cmp::max_by(self, other, Self::total_cmp), + } + } + + /// Get the minimum of two numbers, propagating NaN + /// + /// For this operation, -0.0 is considered to be less than +0.0 as + /// specified in IEEE 754-2019. + #[must_use] + fn minimum(self, other: Self) -> Self { + match (self.is_nan(), other.is_nan()) { + (true, _) => self, + (_, true) => other, + _ => core::cmp::min_by(self, other, Self::total_cmp), + } + } } macro_rules! totalorder_impl { ($T:ident, $I:ident, $U:ident, $bits:expr) => { From 180299c1922dc911749c3c382f0ac8bbeb64fee2 Mon Sep 17 00:00:00 2001 From: Chen-Pang He Date: Thu, 16 May 2024 00:52:31 +0800 Subject: [PATCH 2/2] Move Self: FloatCore requirement to (min|max)imum functions to avoid a breaking change --- src/float.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/float.rs b/src/float.rs index bb1e9ce..d38dd1a 100644 --- a/src/float.rs +++ b/src/float.rs @@ -2245,7 +2245,7 @@ float_const_impl! { /// Trait for floating point numbers that provide an implementation /// of the `totalOrder` predicate as defined in the IEEE 754 (2008 revision) /// floating point standard. -pub trait TotalOrder: FloatCore { +pub trait TotalOrder { /// Return the ordering between `self` and `other`. /// /// Unlike the standard partial comparison between floating point numbers, @@ -2303,7 +2303,10 @@ pub trait TotalOrder: FloatCore { /// For this operation, -0.0 is considered to be less than +0.0 as /// specified in IEEE 754-2019. #[must_use] - fn maximum(self, other: Self) -> Self { + fn maximum(self, other: Self) -> Self + where + Self: FloatCore, + { match (self.is_nan(), other.is_nan()) { (true, _) => self, (_, true) => other, @@ -2316,7 +2319,10 @@ pub trait TotalOrder: FloatCore { /// For this operation, -0.0 is considered to be less than +0.0 as /// specified in IEEE 754-2019. #[must_use] - fn minimum(self, other: Self) -> Self { + fn minimum(self, other: Self) -> Self + where + Self: FloatCore, + { match (self.is_nan(), other.is_nan()) { (true, _) => self, (_, true) => other,