diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 21bd79611a5e5..d3ad0b05cd79e 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -26,6 +26,8 @@ pub use core::f32::{ consts, DIGITS, EPSILON, INFINITY, MANTISSA_DIGITS, MAX, MAX_10_EXP, MAX_EXP, MIN, MIN_10_EXP, MIN_EXP, MIN_POSITIVE, NAN, NEG_INFINITY, RADIX, }; +#[cfg(not(test))] +use core::ops::RangeInclusive; #[cfg(not(test))] #[lang = "f32_runtime"] @@ -902,7 +904,10 @@ impl f32 { /// [finite]: #method.is_finite #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_interpolation", issue = "86269")] - pub fn lerp(self, start: f32, end: f32) -> f32 { + pub fn lerp(self, range: RangeInclusive) -> f32 { + let start = *range.start(); + let end = *range.end(); + // consistent if start == end { start diff --git a/library/std/src/f32/tests.rs b/library/std/src/f32/tests.rs index fe66a73afd63a..edabe5c1756c6 100644 --- a/library/std/src/f32/tests.rs +++ b/library/std/src/f32/tests.rs @@ -761,61 +761,61 @@ fn test_total_cmp() { #[test] fn test_lerp_exact() { // simple values - assert_eq!(f32::lerp(0.0, 2.0, 4.0), 2.0); - assert_eq!(f32::lerp(1.0, 2.0, 4.0), 4.0); + assert_eq!(f32::lerp(0.0, 2.0..=4.0), 2.0); + assert_eq!(f32::lerp(1.0, 2.0..=4.0), 4.0); // boundary values - assert_eq!(f32::lerp(0.0, f32::MIN, f32::MAX), f32::MIN); - assert_eq!(f32::lerp(1.0, f32::MIN, f32::MAX), f32::MAX); + assert_eq!(f32::lerp(0.0, f32::MIN..=f32::MAX), f32::MIN); + assert_eq!(f32::lerp(1.0, f32::MIN..=f32::MAX), f32::MAX); } #[test] fn test_lerp_consistent() { - assert_eq!(f32::lerp(f32::MAX, f32::MIN, f32::MIN), f32::MIN); - assert_eq!(f32::lerp(f32::MIN, f32::MAX, f32::MAX), f32::MAX); + assert_eq!(f32::lerp(f32::MAX, f32::MIN..=f32::MIN), f32::MIN); + assert_eq!(f32::lerp(f32::MIN, f32::MAX..=f32::MAX), f32::MAX); // as long as t is finite, a/b can be infinite - assert_eq!(f32::lerp(f32::MAX, f32::NEG_INFINITY, f32::NEG_INFINITY), f32::NEG_INFINITY); - assert_eq!(f32::lerp(f32::MIN, f32::INFINITY, f32::INFINITY), f32::INFINITY); + assert_eq!(f32::lerp(f32::MAX, f32::NEG_INFINITY..=f32::NEG_INFINITY), f32::NEG_INFINITY); + assert_eq!(f32::lerp(f32::MIN, f32::INFINITY..=f32::INFINITY), f32::INFINITY); } #[test] fn test_lerp_nan_infinite() { // non-finite t is not NaN if a/b different - assert!(!f32::lerp(f32::INFINITY, f32::MIN, f32::MAX).is_nan()); - assert!(!f32::lerp(f32::NEG_INFINITY, f32::MIN, f32::MAX).is_nan()); + assert!(!f32::lerp(f32::INFINITY, f32::MIN..=f32::MAX).is_nan()); + assert!(!f32::lerp(f32::NEG_INFINITY, f32::MIN..=f32::MAX).is_nan()); } #[test] fn test_lerp_values() { // just a few basic values - assert_eq!(f32::lerp(0.25, 1.0, 2.0), 1.25); - assert_eq!(f32::lerp(0.50, 1.0, 2.0), 1.50); - assert_eq!(f32::lerp(0.75, 1.0, 2.0), 1.75); + assert_eq!(f32::lerp(0.25, 1.0..=2.0), 1.25); + assert_eq!(f32::lerp(0.50, 1.0..=2.0), 1.50); + assert_eq!(f32::lerp(0.75, 1.0..=2.0), 1.75); } #[test] fn test_lerp_monotonic() { // near 0 - let below_zero = f32::lerp(-f32::EPSILON, f32::MIN, f32::MAX); - let zero = f32::lerp(0.0, f32::MIN, f32::MAX); - let above_zero = f32::lerp(f32::EPSILON, f32::MIN, f32::MAX); + let below_zero = f32::lerp(-f32::EPSILON, f32::MIN..=f32::MAX); + let zero = f32::lerp(0.0, f32::MIN..=f32::MAX); + let above_zero = f32::lerp(f32::EPSILON, f32::MIN..=f32::MAX); assert!(below_zero <= zero); assert!(zero <= above_zero); assert!(below_zero <= above_zero); // near 0.5 - let below_half = f32::lerp(0.5 - f32::EPSILON, f32::MIN, f32::MAX); - let half = f32::lerp(0.5, f32::MIN, f32::MAX); - let above_half = f32::lerp(0.5 + f32::EPSILON, f32::MIN, f32::MAX); + let below_half = f32::lerp(0.5 - f32::EPSILON, f32::MIN..=f32::MAX); + let half = f32::lerp(0.5, f32::MIN..=f32::MAX); + let above_half = f32::lerp(0.5 + f32::EPSILON, f32::MIN..=f32::MAX); assert!(below_half <= half); assert!(half <= above_half); assert!(below_half <= above_half); // near 1 - let below_one = f32::lerp(1.0 - f32::EPSILON, f32::MIN, f32::MAX); - let one = f32::lerp(1.0, f32::MIN, f32::MAX); - let above_one = f32::lerp(1.0 + f32::EPSILON, f32::MIN, f32::MAX); + let below_one = f32::lerp(1.0 - f32::EPSILON, f32::MIN..=f32::MAX); + let one = f32::lerp(1.0, f32::MIN..=f32::MAX); + let above_one = f32::lerp(1.0 + f32::EPSILON, f32::MIN..=f32::MAX); assert!(below_one <= one); assert!(one <= above_one); assert!(below_one <= above_one); diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 8c8cf73741b51..307713f4cb5f6 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -26,6 +26,8 @@ pub use core::f64::{ consts, DIGITS, EPSILON, INFINITY, MANTISSA_DIGITS, MAX, MAX_10_EXP, MAX_EXP, MIN, MIN_10_EXP, MIN_EXP, MIN_POSITIVE, NAN, NEG_INFINITY, RADIX, }; +#[cfg(not(test))] +use core::ops::RangeInclusive; #[cfg(not(test))] #[lang = "f64_runtime"] @@ -904,7 +906,10 @@ impl f64 { /// [finite]: #method.is_finite #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_interpolation", issue = "86269")] - pub fn lerp(self, start: f64, end: f64) -> f64 { + pub fn lerp(self, range: RangeInclusive) -> f64 { + let start = *range.start(); + let end = *range.end(); + // consistent if start == end { start diff --git a/library/std/src/f64/tests.rs b/library/std/src/f64/tests.rs index 04cb0109261a4..560fd812b254c 100644 --- a/library/std/src/f64/tests.rs +++ b/library/std/src/f64/tests.rs @@ -757,53 +757,53 @@ fn test_total_cmp() { #[test] fn test_lerp_exact() { // simple values - assert_eq!(f64::lerp(0.0, 2.0, 4.0), 2.0); - assert_eq!(f64::lerp(1.0, 2.0, 4.0), 4.0); + assert_eq!(f64::lerp(0.0, 2.0..=4.0), 2.0); + assert_eq!(f64::lerp(1.0, 2.0..=4.0), 4.0); // boundary values - assert_eq!(f64::lerp(0.0, f64::MIN, f64::MAX), f64::MIN); - assert_eq!(f64::lerp(1.0, f64::MIN, f64::MAX), f64::MAX); + assert_eq!(f64::lerp(0.0, f64::MIN..=f64::MAX), f64::MIN); + assert_eq!(f64::lerp(1.0, f64::MIN..=f64::MAX), f64::MAX); } #[test] fn test_lerp_consistent() { - assert_eq!(f64::lerp(f64::MAX, f64::MIN, f64::MIN), f64::MIN); - assert_eq!(f64::lerp(f64::MIN, f64::MAX, f64::MAX), f64::MAX); + assert_eq!(f64::lerp(f64::MAX, f64::MIN..=f64::MIN), f64::MIN); + assert_eq!(f64::lerp(f64::MIN, f64::MAX..=f64::MAX), f64::MAX); // as long as t is finite, a/b can be infinite - assert_eq!(f64::lerp(f64::MAX, f64::NEG_INFINITY, f64::NEG_INFINITY), f64::NEG_INFINITY); - assert_eq!(f64::lerp(f64::MIN, f64::INFINITY, f64::INFINITY), f64::INFINITY); + assert_eq!(f64::lerp(f64::MAX, f64::NEG_INFINITY..=f64::NEG_INFINITY), f64::NEG_INFINITY); + assert_eq!(f64::lerp(f64::MIN, f64::INFINITY..=f64::INFINITY), f64::INFINITY); } #[test] fn test_lerp_nan_infinite() { // non-finite t is not NaN if a/b different - assert!(!f64::lerp(f64::INFINITY, f64::MIN, f64::MAX).is_nan()); - assert!(!f64::lerp(f64::NEG_INFINITY, f64::MIN, f64::MAX).is_nan()); + assert!(!f64::lerp(f64::INFINITY, f64::MIN..=f64::MAX).is_nan()); + assert!(!f64::lerp(f64::NEG_INFINITY, f64::MIN..=f64::MAX).is_nan()); } #[test] fn test_lerp_values() { // just a few basic values - assert_eq!(f64::lerp(0.25, 1.0, 2.0), 1.25); - assert_eq!(f64::lerp(0.50, 1.0, 2.0), 1.50); - assert_eq!(f64::lerp(0.75, 1.0, 2.0), 1.75); + assert_eq!(f64::lerp(0.25, 1.0..=2.0), 1.25); + assert_eq!(f64::lerp(0.50, 1.0..=2.0), 1.50); + assert_eq!(f64::lerp(0.75, 1.0..=2.0), 1.75); } #[test] fn test_lerp_monotonic() { // near 0 - let below_zero = f64::lerp(-f64::EPSILON, f64::MIN, f64::MAX); - let zero = f64::lerp(0.0, f64::MIN, f64::MAX); - let above_zero = f64::lerp(f64::EPSILON, f64::MIN, f64::MAX); + let below_zero = f64::lerp(-f64::EPSILON, f64::MIN..=f64::MAX); + let zero = f64::lerp(0.0, f64::MIN..=f64::MAX); + let above_zero = f64::lerp(f64::EPSILON, f64::MIN..=f64::MAX); assert!(below_zero <= zero); assert!(zero <= above_zero); assert!(below_zero <= above_zero); // near 1 - let below_one = f64::lerp(1.0 - f64::EPSILON, f64::MIN, f64::MAX); - let one = f64::lerp(1.0, f64::MIN, f64::MAX); - let above_one = f64::lerp(1.0 + f64::EPSILON, f64::MIN, f64::MAX); + let below_one = f64::lerp(1.0 - f64::EPSILON, f64::MIN..=f64::MAX); + let one = f64::lerp(1.0, f64::MIN..=f64::MAX); + let above_one = f64::lerp(1.0 + f64::EPSILON, f64::MIN..=f64::MAX); assert!(below_one <= one); assert!(one <= above_one); assert!(below_one <= above_one);