authorgravatar for github@mjb.ioMichael Bradshaw <github@mjb.io> 2023-10-20 07:20:01-06:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-10-21 20:51:51+03:00
logcc56577edfadd7685de7fb14c013c5e3a69c28ce
tree4bef172448f765f0526324bdd23f6ff1fc98910b
parentb403ca0aabb4529949b48e68f1392afc31098a98

Return zero for NaN-to-int lossy casts

Fixes #15038. The goal here is to guarantee lossyCast() is panic-free and always safe.

1 files changed, 4 insertions(+), 1 deletions(-)

lib/std/math.zig+4-1
...@@ -1214,7 +1214,9 @@ pub fn lossyCast(comptime T: type, value: anytype) T {...@@ -1214,7 +1214,9 @@ pub fn lossyCast(comptime T: type, value: anytype) T {
1214 }1214 }
1215 },1215 },
1216 .Float, .ComptimeFloat => {1216 .Float, .ComptimeFloat => {
1217 if (value >= maxInt(T)) {1217 if (isNan(value)) {
1218 return 0;
1219 } else if (value >= maxInt(T)) {
1218 return @as(T, maxInt(T));1220 return @as(T, maxInt(T));
1219 } else if (value <= minInt(T)) {1221 } else if (value <= minInt(T)) {
1220 return @as(T, minInt(T));1222 return @as(T, minInt(T));
...@@ -1234,6 +1236,7 @@ test "lossyCast" {...@@ -1234,6 +1236,7 @@ test "lossyCast" {
1234 try testing.expect(lossyCast(u32, @as(i16, -255)) == @as(u32, 0));1236 try testing.expect(lossyCast(u32, @as(i16, -255)) == @as(u32, 0));
1235 try testing.expect(lossyCast(i9, @as(u32, 200)) == @as(i9, 200));1237 try testing.expect(lossyCast(i9, @as(u32, 200)) == @as(i9, 200));
1236 try testing.expect(lossyCast(u32, @as(f32, maxInt(u32))) == maxInt(u32));1238 try testing.expect(lossyCast(u32, @as(f32, maxInt(u32))) == maxInt(u32));
1239 try testing.expect(lossyCast(u32, nan(f32)) == 0);
1237}1240}
12381241
1239/// Performs linear interpolation between *a* and *b* based on *t*.1242/// Performs linear interpolation between *a* and *b* based on *t*.