diff --git a/lib/std/math.zig b/lib/std/math.zig index 9f2d12a65e..c36f19ec85 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -1345,11 +1345,15 @@ pub fn lossyCast(comptime T: type, value: anytype) T { } }, .float, .comptime_float => { + // In extreme cases, we probably need a language enhancement to be able to + // specify a rounding mode here to prevent `@intFromFloat` panics. + const max: @TypeOf(value) = @floatFromInt(maxInt(T)); + const min: @TypeOf(value) = @floatFromInt(minInt(T)); if (isNan(value)) { return 0; - } else if (value >= maxInt(T)) { + } else if (value >= max) { return maxInt(T); - } else if (value <= minInt(T)) { + } else if (value <= min) { return minInt(T); } else { return @intFromFloat(value); @@ -1366,7 +1370,7 @@ test lossyCast { try testing.expect(lossyCast(i16, 70000.0) == @as(i16, 32767)); try testing.expect(lossyCast(u32, @as(i16, -255)) == @as(u32, 0)); try testing.expect(lossyCast(i9, @as(u32, 200)) == @as(i9, 200)); - try testing.expect(lossyCast(u32, @as(f32, maxInt(u32))) == maxInt(u32)); + try testing.expect(lossyCast(u32, @as(f32, @floatFromInt(maxInt(u32)))) == maxInt(u32)); try testing.expect(lossyCast(u32, nan(f32)) == 0); } diff --git a/lib/std/math/gamma.zig b/lib/std/math/gamma.zig index 5577f71461..ce9a2b07f9 100644 --- a/lib/std/math/gamma.zig +++ b/lib/std/math/gamma.zig @@ -189,19 +189,19 @@ fn series(comptime T: type, abs: T) T { 2.5066282746310002701649081771338373386264310793408, }; const denominator = [_]T{ - 0, - 39916800, - 120543840, - 150917976, - 105258076, - 45995730, - 13339535, - 2637558, - 357423, - 32670, - 1925, - 66, - 1, + 0.0, + 39916800.0, + 120543840.0, + 150917976.0, + 105258076.0, + 45995730.0, + 13339535.0, + 2637558.0, + 357423.0, + 32670.0, + 1925.0, + 66.0, + 1.0, }; var num: T = 0; var den: T = 0; @@ -244,9 +244,9 @@ const expectApproxEqRel = std.testing.expectApproxEqRel; test gamma { inline for (&.{ f32, f64 }) |T| { const eps = @sqrt(std.math.floatEps(T)); - try expectApproxEqRel(@as(T, 120), gamma(T, 6), eps); - try expectApproxEqRel(@as(T, 362880), gamma(T, 10), eps); - try expectApproxEqRel(@as(T, 6402373705728000), gamma(T, 19), eps); + try expectApproxEqRel(@as(T, 120.0), gamma(T, 6), eps); + try expectApproxEqRel(@as(T, 362880.0), gamma(T, 10), eps); + try expectApproxEqRel(@as(T, 6402373705728000.0), gamma(T, 19), eps); try expectApproxEqRel(@as(T, 332.7590766955334570), gamma(T, 0.003), eps); try expectApproxEqRel(@as(T, 1.377260301981044573), gamma(T, 0.654), eps); diff --git a/lib/std/math/modf.zig b/lib/std/math/modf.zig index 77d58bd34e..dda34454e3 100644 --- a/lib/std/math/modf.zig +++ b/lib/std/math/modf.zig @@ -74,7 +74,7 @@ fn ModfTests(comptime T: type) type { r = modf(@as(T, 43874.3)); try expectEqual(43874.0, r.ipart); // account for precision error - const expected_b: T = 43874.3 - @as(T, 43874); + const expected_b: T = 43874.3 - @as(T, 43874.0); try expectApproxEqAbs(expected_b, r.fpart, epsilon); r = modf(@as(T, 1234.340780)); diff --git a/lib/std/math/pow.zig b/lib/std/math/pow.zig index acaafe7609..42f28ce465 100644 --- a/lib/std/math/pow.zig +++ b/lib/std/math/pow.zig @@ -192,8 +192,8 @@ fn isOddInteger(x: f64) bool { } test isOddInteger { - try expect(isOddInteger(math.maxInt(i64) * 2) == false); - try expect(isOddInteger(math.maxInt(i64) * 2 + 1) == false); + try expect(isOddInteger(@floatFromInt(math.maxInt(i64) * 2)) == false); + try expect(isOddInteger(@floatFromInt(math.maxInt(i64) * 2 + 1)) == false); try expect(isOddInteger(1 << 53) == false); try expect(isOddInteger(12.0) == false); try expect(isOddInteger(15.0) == true); diff --git a/lib/std/zon/parse.zig b/lib/std/zon/parse.zig index 96a7fa6595..5f74400c29 100644 --- a/lib/std/zon/parse.zig +++ b/lib/std/zon/parse.zig @@ -2774,11 +2774,11 @@ test "std.zon parse float" { // Test big integers try std.testing.expectEqual( - @as(f32, 36893488147419103231), + @as(f32, 36893488147419103231.0), try fromSlice(f32, gpa, "36893488147419103231", null, .{}), ); try std.testing.expectEqual( - @as(f32, -36893488147419103231), + @as(f32, -36893488147419103231.0), try fromSlice(f32, gpa, "-36893488147419103231", null, .{}), ); try std.testing.expectEqual(@as(f128, 0x1ffffffffffffffff), try fromSlice( @@ -2788,7 +2788,7 @@ test "std.zon parse float" { null, .{}, )); - try std.testing.expectEqual(@as(f32, 0x1ffffffffffffffff), try fromSlice( + try std.testing.expectEqual(@as(f32, @floatFromInt(0x1ffffffffffffffff)), try fromSlice( f32, gpa, "0x1ffffffffffffffff",