diff --git a/src/lib.rs b/src/lib.rs index 172e714..010ccf1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -371,17 +371,55 @@ pub fn clamp(input: T, min: T, max: T) -> T { } } +/// A value bounded by a minimum value +/// +/// If input is less than min then this returns min. +/// Otherwise this returns input. +/// Preserves `NaN` different from `min`. +#[inline] +pub fn clamp_lower(input: T, min: T) -> T { + if input < min { + min + } else { + input + } +} + +/// A value bounded by a maximum value +/// +/// If input is less than min then this returns min. +/// Otherwise this returns input. +/// Preserves `NaN` different from `max`. +#[inline] +pub fn clamp_upper(input: T, max: T) -> T { + if input > max { + max + } else { + input + } +} + #[test] fn clamp_test() { // Int test assert_eq!(1, clamp(1, -1, 2)); assert_eq!(-1, clamp(-2, -1, 2)); assert_eq!(2, clamp(3, -1, 2)); + assert_eq!(1, clamp_lower(1, -1)); + assert_eq!(-1, clamp_lower(-2, -1)); + assert_eq!(-1, clamp_upper(1, -1)); + assert_eq!(-2, clamp_upper(-2, -1)); // Float test assert_eq!(1.0, clamp(1.0, -1.0, 2.0)); assert_eq!(-1.0, clamp(-2.0, -1.0, 2.0)); assert_eq!(2.0, clamp(3.0, -1.0, 2.0)); + assert_eq!(1.0, clamp_lower(1.0, -1.0)); + assert_eq!(-1.0, clamp_lower(-2.0, -1.0)); + assert_eq!(-1.0, clamp_upper(1.0, -1.0)); + assert_eq!(-2.0, clamp_upper(-2.0, -1.0)); + assert!(clamp_lower(std::f32::NAN, 1.0).is_nan()); + assert!(clamp_upper(std::f32::NAN, 1.0).is_nan()); } #[test]