@@ -1312,6 +1312,33 @@ test "lossyCast" {
1312
1312
try testing .expect (lossyCast (u32 , @as (f32 , maxInt (u32 ))) == maxInt (u32 ));
1313
1313
}
1314
1314
1315
+ /// Performs linear interpolation between *a* and *b* based on *t*.
1316
+ /// *t* must be in range 0.0 to 1.0. T must be a float type.
1317
+ ///
1318
+ /// This does not guarantee returning *b* if *t* is 1 due to floating-point errors.
1319
+ /// This is monotonic.
1320
+ pub fn lerp (comptime T : type , a : T , b : T , t : T ) T {
1321
+ if (@typeInfo (T ) != .Float and @typeInfo (T ) != .ComptimeFloat )
1322
+ @compileError ("T must be a float type" );
1323
+
1324
+ assert (t >= 0 and t <= 1 );
1325
+ return @mulAdd (T , b - a , t , a );
1326
+ }
1327
+
1328
+ test "lerp" {
1329
+ try testing .expectEqual (@as (f16 , 75 ), lerp (f16 , 50 , 100 , 0.5 ));
1330
+ try testing .expectEqual (@as (f32 , 43.75 ), lerp (f32 , 50 , 25 , 0.25 ));
1331
+ try testing .expectEqual (@as (f64 , -31.25 ), lerp (f64 , -50 , 25 , 0.25 ));
1332
+ try testing .expectApproxEqRel (@as (f80 , -7.16067345e+03 ), lerp (f80 , -10000.12345 , -5000.12345 , 0.56789 ), 1e-19 );
1333
+ try testing .expectApproxEqRel (@as (f128 , 7.010987590521e+62 ), lerp (f128 , 0.123456789e-64 , 0.123456789e64 , 0.56789 ), 1e-33 );
1334
+
1335
+ // this highlights the precision
1336
+ try testing .expectEqual (@as (f32 , 0.0 ), lerp (f32 , 1.0e8 , 1.0 , 1.0 ));
1337
+ try testing .expectEqual (@as (f16 , 0.0 ), lerp (f16 , 1.0e4 , 1.0 , 1.0 ));
1338
+ try testing .expectEqual (@as (f32 , 1.0 ), lerp (f32 , 1.0e7 , 1.0 , 1.0 ));
1339
+ try testing .expectEqual (@as (f16 , 1.0 ), lerp (f16 , 1.0e3 , 1.0 , 1.0 ));
1340
+ }
1341
+
1315
1342
/// Returns the maximum value of integer type T.
1316
1343
pub fn maxInt (comptime T : type ) comptime_int {
1317
1344
const info = @typeInfo (T );
0 commit comments