From 295704408f524c7df8f036eb875f48e6b998d693 Mon Sep 17 00:00:00 2001 From: Michael Ciraci Date: Fri, 19 Jan 2024 14:20:21 -0600 Subject: [PATCH 1/2] Implementing clamp for Float trait --- src/float.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/float.rs b/src/float.rs index 7a42dd8..71102f2 100644 --- a/src/float.rs +++ b/src/float.rs @@ -652,6 +652,36 @@ pub trait FloatCore: Num + NumCast + Neg + PartialOrd + Copy { } } + /// A value bounded by a minimum and a maximum + /// + /// If input is less than min then this returns min. + /// If input is greater than max then this returns max. + /// Otherwise this returns input. + /// + /// **Panics** in debug mode if `!(min <= max)`. + /// + /// # Examples + /// + /// ``` + /// use num_traits::float::FloatCore; + /// + /// fn check(val: T, min: T, max: T, expected: T) { + /// assert!(val.clamp(min, max) == expected); + /// } + /// + /// + /// check(1.0f32, 0.0, 2.0, 1.0); + /// check(1.0f32, 2.0, 3.0, 2.0); + /// check(3.0f32, 0.0, 2.0, 2.0); + /// + /// check(1.0f64, 0.0, 2.0, 1.0); + /// check(1.0f64, 2.0, 3.0, 2.0); + /// check(3.0f64, 0.0, 2.0, 2.0); + /// ``` + fn clamp(self, min: Self, max: Self) -> Self { + crate::clamp(self, min, max) + } + /// Returns the reciprocal (multiplicative inverse) of the number. /// /// # Examples @@ -791,6 +821,7 @@ impl FloatCore for f32 { Self::is_finite(self) -> bool; Self::is_normal(self) -> bool; Self::is_subnormal(self) -> bool; + Self::clamp(self, min: Self, max: Self) -> Self; Self::classify(self) -> FpCategory; Self::is_sign_positive(self) -> bool; Self::is_sign_negative(self) -> bool; @@ -852,6 +883,7 @@ impl FloatCore for f64 { Self::is_finite(self) -> bool; Self::is_normal(self) -> bool; Self::is_subnormal(self) -> bool; + Self::clamp(self, min: Self, max: Self) -> Self; Self::classify(self) -> FpCategory; Self::is_sign_positive(self) -> bool; Self::is_sign_negative(self) -> bool; @@ -1497,6 +1529,19 @@ pub trait Float: Num + Copy + NumCast + PartialOrd + Neg { /// ``` fn min(self, other: Self) -> Self; + /// Clamps a value between a min and max. + /// + /// ``` + /// use num_traits::Float; + /// + /// let x = 1.0; + /// let y = 2.0; + /// let z = 3.0; + /// + /// assert_eq!(x.clamp(y, z), 2.0); + /// ``` + fn clamp(self, min: Self, max: Self) -> Self; + /// The positive difference of two numbers. /// /// * If `self <= other`: `0:0` @@ -1895,6 +1940,7 @@ macro_rules! float_impl_std { Self::is_normal(self) -> bool; Self::is_subnormal(self) -> bool; Self::classify(self) -> FpCategory; + Self::clamp(self, min: Self, max: Self) -> Self; Self::floor(self) -> Self; Self::ceil(self) -> Self; Self::round(self) -> Self; @@ -1978,6 +2024,7 @@ macro_rules! float_impl_libm { Self::is_finite(self) -> bool; Self::is_normal(self) -> bool; Self::is_subnormal(self) -> bool; + Self::clamp(self, min: Self, max: Self) -> Self; Self::classify(self) -> FpCategory; Self::is_sign_positive(self) -> bool; Self::is_sign_negative(self) -> bool; From 1a44ffb9deb4d76988b6ea6bc2767ed40264aac3 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 3 May 2024 13:44:21 -0700 Subject: [PATCH 2/2] Add a default impl for `Float::clamp` --- src/float.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/float.rs b/src/float.rs index 71102f2..d0d21a5 100644 --- a/src/float.rs +++ b/src/float.rs @@ -1531,6 +1531,8 @@ pub trait Float: Num + Copy + NumCast + PartialOrd + Neg { /// Clamps a value between a min and max. /// + /// **Panics** in debug mode if `!(min <= max)`. + /// /// ``` /// use num_traits::Float; /// @@ -1540,7 +1542,9 @@ pub trait Float: Num + Copy + NumCast + PartialOrd + Neg { /// /// assert_eq!(x.clamp(y, z), 2.0); /// ``` - fn clamp(self, min: Self, max: Self) -> Self; + fn clamp(self, min: Self, max: Self) -> Self { + crate::clamp(self, min, max) + } /// The positive difference of two numbers. ///