From 0f32de77c91a3761a4434d1790018b5c2c6fa099 Mon Sep 17 00:00:00 2001 From: Adam Goertz Date: Tue, 27 Oct 2020 22:55:12 -0400 Subject: [PATCH 1/2] impl lossyCast #5080 --- lib/std/math.zig | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/lib/std/math.zig b/lib/std/math.zig index 9bc5d75ae2..94915a5ad0 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -1070,16 +1070,44 @@ test "std.math.log2_int_ceil" { testing.expect(log2_int_ceil(u32, 10) == 4); } +///Cast a value to a different type. If the value doesn't fit in, or can't be perfectly represented by, +///the new type, it will be converted to the closest possible representation. pub fn lossyCast(comptime T: type, value: anytype) T { - switch (@typeInfo(@TypeOf(value))) { - .Int => return @intToFloat(T, value), - .Float => return @floatCast(T, value), - .ComptimeInt => return @as(T, value), - .ComptimeFloat => return @as(T, value), - else => @compileError("bad type"), + switch(@typeInfo(T)) { + .Float => { + switch (@typeInfo(@TypeOf(value))) { + .Int => return @intToFloat(T, value), + .Float => return @floatCast(T, value), + .ComptimeInt => return @as(T, value), + .ComptimeFloat => return @as(T, value), + else => @compileError("bad type"), + } + }, + .Int => { + switch(@typeInfo(@TypeOf(value))) { + .Int, .ComptimeInt => { + if (value > maxInt(T)) { return @as(T, maxInt(T)); } + else if (value < minInt(T)) { return @as(T, minInt(T)); } + else { return @intCast(T, value); } + }, + .Float, .ComptimeFloat => { + if (value > maxInt(T)) { return @as(T, maxInt(T)); } + else if (value < minInt(T)) { return @as(T, minInt(T)); } + else { return @floatToInt(T, value); } + }, + else => @compileError("bad type"), + } + }, + else => @compileError("bad result type"), } } +test "math.lossyCast" { + testing.expect(lossyCast(i16, 70000.0) == @as(i16, 32767)); + testing.expect(lossyCast(u32, @as(i16, -255)) == @as(u32, 0)); + testing.expect(lossyCast(i9, @as(u32, 200)) == @as(i9, 200)); +} + test "math.f64_min" { const f64_min_u64 = 0x0010000000000000; const fmin: f64 = f64_min; From 169810b20fb6ce036ed0ff2990f06751aa11e623 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 10 Jan 2021 19:04:10 -0700 Subject: [PATCH 2/2] zig fmt --- lib/std/math.zig | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/std/math.zig b/lib/std/math.zig index 94915a5ad0..77eed37304 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -1073,7 +1073,7 @@ test "std.math.log2_int_ceil" { ///Cast a value to a different type. If the value doesn't fit in, or can't be perfectly represented by, ///the new type, it will be converted to the closest possible representation. pub fn lossyCast(comptime T: type, value: anytype) T { - switch(@typeInfo(T)) { + switch (@typeInfo(T)) { .Float => { switch (@typeInfo(@TypeOf(value))) { .Int => return @intToFloat(T, value), @@ -1084,16 +1084,24 @@ pub fn lossyCast(comptime T: type, value: anytype) T { } }, .Int => { - switch(@typeInfo(@TypeOf(value))) { + switch (@typeInfo(@TypeOf(value))) { .Int, .ComptimeInt => { - if (value > maxInt(T)) { return @as(T, maxInt(T)); } - else if (value < minInt(T)) { return @as(T, minInt(T)); } - else { return @intCast(T, value); } + if (value > maxInt(T)) { + return @as(T, maxInt(T)); + } else if (value < minInt(T)) { + return @as(T, minInt(T)); + } else { + return @intCast(T, value); + } }, .Float, .ComptimeFloat => { - if (value > maxInt(T)) { return @as(T, maxInt(T)); } - else if (value < minInt(T)) { return @as(T, minInt(T)); } - else { return @floatToInt(T, value); } + if (value > maxInt(T)) { + return @as(T, maxInt(T)); + } else if (value < minInt(T)) { + return @as(T, minInt(T)); + } else { + return @floatToInt(T, value); + } }, else => @compileError("bad type"), }