authorgravatar for adambgoertz@gmail.comAdam Goertz <adambgoertz@gmail.com> 2020-10-27 22:55:12-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-10 19:02:41-07:00
log0f32de77c91a3761a4434d1790018b5c2c6fa099
treea1f8a13794bb2553aaf483360df3059a4bf58e03
parente1d8073d2fc0df6fbc5ce983312e3da374a9889b

impl lossyCast #5080


1 files changed, 34 insertions(+), 6 deletions(-)

lib/std/math.zig+34-6
......@@ -1070,16 +1070,44 @@ test "std.math.log2_int_ceil" {
10701070 testing.expect(log2_int_ceil(u32, 10) == 4);
10711071}
10721072
1073///Cast a value to a different type. If the value doesn't fit in, or can't be perfectly represented by,
1074///the new type, it will be converted to the closest possible representation.
10731075pub fn lossyCast(comptime T: type, value: anytype) T {
1074 switch (@typeInfo(@TypeOf(value))) {
1075 .Int => return @intToFloat(T, value),
1076 .Float => return @floatCast(T, value),
1077 .ComptimeInt => return @as(T, value),
1078 .ComptimeFloat => return @as(T, value),
1079 else => @compileError("bad type"),
1076 switch(@typeInfo(T)) {
1077 .Float => {
1078 switch (@typeInfo(@TypeOf(value))) {
1079 .Int => return @intToFloat(T, value),
1080 .Float => return @floatCast(T, value),
1081 .ComptimeInt => return @as(T, value),
1082 .ComptimeFloat => return @as(T, value),
1083 else => @compileError("bad type"),
1084 }
1085 },
1086 .Int => {
1087 switch(@typeInfo(@TypeOf(value))) {
1088 .Int, .ComptimeInt => {
1089 if (value > maxInt(T)) { return @as(T, maxInt(T)); }
1090 else if (value < minInt(T)) { return @as(T, minInt(T)); }
1091 else { return @intCast(T, value); }
1092 },
1093 .Float, .ComptimeFloat => {
1094 if (value > maxInt(T)) { return @as(T, maxInt(T)); }
1095 else if (value < minInt(T)) { return @as(T, minInt(T)); }
1096 else { return @floatToInt(T, value); }
1097 },
1098 else => @compileError("bad type"),
1099 }
1100 },
1101 else => @compileError("bad result type"),
10801102 }
10811103}
10821104
1105test "math.lossyCast" {
1106 testing.expect(lossyCast(i16, 70000.0) == @as(i16, 32767));
1107 testing.expect(lossyCast(u32, @as(i16, -255)) == @as(u32, 0));
1108 testing.expect(lossyCast(i9, @as(u32, 200)) == @as(i9, 200));
1109}
1110
10831111test "math.f64_min" {
10841112 const f64_min_u64 = 0x0010000000000000;
10851113 const fmin: f64 = f64_min;