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
pub fn lossyCast(comptime T: type, value: anytype) T {
switch (@typeInfo(T)) {
.float => {
switch (@typeInfo(@TypeOf(value))) {
.int => return @floatFromInt(value),
.float => return @floatCast(value),
.comptime_int => return value,
.comptime_float => return value,
else => @compileError("bad type"),
}
},
.int => {
switch (@typeInfo(@TypeOf(value))) {
.int, .comptime_int => {
if (value >= maxInt(T)) {
return maxInt(T);
} else if (value <= minInt(T)) {
return minInt(T);
} else {
return @intCast(value);
}
},
.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 >= max) {
return maxInt(T);
} else if (value <= min) {
return minInt(T);
} else {
return @intFromFloat(value);
}
},
else => @compileError("bad type"),
}
},
else => @compileError("bad result type"),
}
}