@@ -1279,6 +1279,33 @@ test "lossyCast" {
1279
1279
try testing .expect (lossyCast (u32 , @as (f32 , maxInt (u32 ))) == maxInt (u32 ));
1280
1280
}
1281
1281
1282
+ /// Performs linear interpolation between *a* and *b* based on *t*.
1283
+ /// *t* must be in range 0.0 to 1.0. T must be a float type.
1284
+ ///
1285
+ /// This does not guarantee returning *b* if *t* is 1 due to floating-point errors.
1286
+ /// This is monotonic.
1287
+ pub fn lerp (comptime T : type , a : T , b : T , t : T ) T {
1288
+ if (@typeInfo (T ) != .Float and @typeInfo (T ) != .ComptimeFloat )
1289
+ @compileError ("T must be a float type" );
1290
+
1291
+ assert (t >= 0 and t <= 1 );
1292
+ return @mulAdd (T , b - a , t , a );
1293
+ }
1294
+
1295
+ test "lerp" {
1296
+ try testing .expectEqual (@as (f16 , 75 ), lerp (f16 , 50 , 100 , 0.5 ));
1297
+ try testing .expectEqual (@as (f32 , 43.75 ), lerp (f32 , 50 , 25 , 0.25 ));
1298
+ try testing .expectEqual (@as (f64 , -31.25 ), lerp (f64 , -50 , 25 , 0.25 ));
1299
+ try testing .expectApproxEqRel (@as (f80 , -7.16067345e+03 ), lerp (f80 , -10000.12345 , -5000.12345 , 0.56789 ), 1e-19 );
1300
+ try testing .expectApproxEqRel (@as (f128 , 7.010987590521e+62 ), lerp (f128 , 0.123456789e-64 , 0.123456789e64 , 0.56789 ), 1e-33 );
1301
+
1302
+ // this highlights the precision
1303
+ try testing .expectEqual (@as (f32 , 0.0 ), lerp (f32 , 1.0e8 , 1.0 , 1.0 ));
1304
+ try testing .expectEqual (@as (f16 , 0.0 ), lerp (f16 , 1.0e4 , 1.0 , 1.0 ));
1305
+ try testing .expectEqual (@as (f32 , 1.0 ), lerp (f32 , 1.0e7 , 1.0 , 1.0 ));
1306
+ try testing .expectEqual (@as (f16 , 1.0 ), lerp (f16 , 1.0e3 , 1.0 , 1.0 ));
1307
+ }
1308
+
1282
1309
/// Returns the maximum value of integer type T.
1283
1310
pub fn maxInt (comptime T : type ) comptime_int {
1284
1311
const info = @typeInfo (T );
0 commit comments