about summary refs log tree commit diff
diff options
context:
space:
mode:
authorltdk <usr@ltdk.xyz>2021-06-01 22:50:42 -0400
committerltdk <usr@ltdk.xyz>2021-06-01 23:09:46 -0400
commitf310d0e5003cde10959eba46dd969f37b8089382 (patch)
tree5076b533a17c71771fe407240a05a811ea572416
parent625d5a693e4697bcafdd34fd1a38c281acabb8e9 (diff)
downloadrust-f310d0e5003cde10959eba46dd969f37b8089382.tar.gz
rust-f310d0e5003cde10959eba46dd969f37b8089382.zip
Add lerp method
-rw-r--r--library/std/src/f32.rs28
-rw-r--r--library/std/src/f64.rs28
2 files changed, 56 insertions, 0 deletions
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index c16d27fa1f5..32a4d415362 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -876,4 +876,32 @@ impl f32 {
     pub fn atanh(self) -> f32 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
+
+    /// Linear interpolation between `start` and `end`.
+    ///
+    /// This enables the calculation of a "smooth" transition between `start` and `end`,
+    /// where start is represented by `self == 0.0` and `end` is represented by `self == 1.0`.
+    ///
+    /// Values below 0.0 or above 1.0 are allowed, and in general this function closely
+    /// resembles the value of `start + self * (end - start)`, plus additional guarantees.
+    ///
+    /// Those guarantees are, assuming that all values are [`finite`]:
+    ///
+    /// * The value at 0.0 is always `start` and the value at 1.0 is always `end` (exactness)
+    /// * If `start == end`, the value at any point will always be `start == end` (consistency)
+    /// * The values will always move in the direction from `start` to `end` (monotonicity)
+    ///
+    /// [`finite`]: #method.is_finite
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_interpolation", issue = "71015")]
+    pub fn lerp(self, start: f32, end: f32) -> f32 {
+        // consistent
+        if start == end {
+            start
+
+        // exact/monotonic
+        } else {
+            self.mul_add(end, (-self).mul_add(start, start))
+        }
+    }
 }
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index 4c95df5ffe0..39c3e587e1f 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -879,6 +879,34 @@ impl f64 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
 
+    /// Linear interpolation between `start` and `end`.
+    ///
+    /// This enables the calculation of a "smooth" transition between `start` and `end`,
+    /// where start is represented by `self == 0.0` and `end` is represented by `self == 1.0`.
+    ///
+    /// Values below 0.0 or above 1.0 are allowed, and in general this function closely
+    /// resembles the value of `start + self * (end - start)`, plus additional guarantees.
+    ///
+    /// Those guarantees are, assuming that all values are [`finite`]:
+    ///
+    /// * The value at 0.0 is always `start` and the value at 1.0 is always `end` (exactness)
+    /// * If `start == end`, the value at any point will always be `start == end` (consistency)
+    /// * The values will always move in the direction from `start` to `end` (monotonicity)
+    ///
+    /// [`finite`]: #method.is_finite
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_interpolation", issue = "71015")]
+    pub fn lerp(self, start: f64, end: f64) -> f64 {
+        // consistent
+        if start == end {
+            start
+
+        // exact/monotonic
+        } else {
+            self.mul_add(end, (-self).mul_add(start, start))
+        }
+    }
+
     // Solaris/Illumos requires a wrapper around log, log2, and log10 functions
     // because of their non-standard behavior (e.g., log(-n) returns -Inf instead
     // of expected NaN).