Skip to content

Commit f310d0e

Browse files
committed
Add lerp method
1 parent 625d5a6 commit f310d0e

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

library/std/src/f32.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,4 +876,32 @@ impl f32 {
876876
pub fn atanh(self) -> f32 {
877877
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
878878
}
879+
880+
/// Linear interpolation between `start` and `end`.
881+
///
882+
/// This enables the calculation of a "smooth" transition between `start` and `end`,
883+
/// where start is represented by `self == 0.0` and `end` is represented by `self == 1.0`.
884+
///
885+
/// Values below 0.0 or above 1.0 are allowed, and in general this function closely
886+
/// resembles the value of `start + self * (end - start)`, plus additional guarantees.
887+
///
888+
/// Those guarantees are, assuming that all values are [`finite`]:
889+
///
890+
/// * The value at 0.0 is always `start` and the value at 1.0 is always `end` (exactness)
891+
/// * If `start == end`, the value at any point will always be `start == end` (consistency)
892+
/// * The values will always move in the direction from `start` to `end` (monotonicity)
893+
///
894+
/// [`finite`]: #method.is_finite
895+
#[must_use = "method returns a new number and does not mutate the original value"]
896+
#[unstable(feature = "float_interpolation", issue = "71015")]
897+
pub fn lerp(self, start: f32, end: f32) -> f32 {
898+
// consistent
899+
if start == end {
900+
start
901+
902+
// exact/monotonic
903+
} else {
904+
self.mul_add(end, (-self).mul_add(start, start))
905+
}
906+
}
879907
}

library/std/src/f64.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,34 @@ impl f64 {
879879
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
880880
}
881881

882+
/// Linear interpolation between `start` and `end`.
883+
///
884+
/// This enables the calculation of a "smooth" transition between `start` and `end`,
885+
/// where start is represented by `self == 0.0` and `end` is represented by `self == 1.0`.
886+
///
887+
/// Values below 0.0 or above 1.0 are allowed, and in general this function closely
888+
/// resembles the value of `start + self * (end - start)`, plus additional guarantees.
889+
///
890+
/// Those guarantees are, assuming that all values are [`finite`]:
891+
///
892+
/// * The value at 0.0 is always `start` and the value at 1.0 is always `end` (exactness)
893+
/// * If `start == end`, the value at any point will always be `start == end` (consistency)
894+
/// * The values will always move in the direction from `start` to `end` (monotonicity)
895+
///
896+
/// [`finite`]: #method.is_finite
897+
#[must_use = "method returns a new number and does not mutate the original value"]
898+
#[unstable(feature = "float_interpolation", issue = "71015")]
899+
pub fn lerp(self, start: f64, end: f64) -> f64 {
900+
// consistent
901+
if start == end {
902+
start
903+
904+
// exact/monotonic
905+
} else {
906+
self.mul_add(end, (-self).mul_add(start, start))
907+
}
908+
}
909+
882910
// Solaris/Illumos requires a wrapper around log, log2, and log10 functions
883911
// because of their non-standard behavior (e.g., log(-n) returns -Inf instead
884912
// of expected NaN).

0 commit comments

Comments
 (0)