Skip to content

Instantly share code, notes, and snippets.

@castholm
Last active April 14, 2024 14:55
Show Gist options
  • Save castholm/94a4fea1cee0f72dbdeca7b77f8cb280 to your computer and use it in GitHub Desktop.
Save castholm/94a4fea1cee0f72dbdeca7b77f8cb280 to your computer and use it in GitHub Desktop.
`@truncate` int-from-float
const std = @import("std");
pub const std_options: std.Options = .{
.log_level = .debug,
};
pub fn main() !void {
var timer = try std.time.Timer.start();
var prev: u64 = 0;
var iterations: usize = 0;
var float: f32 = 0;
while (float < 4_194_304) : ({
iterations += 1;
float += 0.25;
}) {
compare(u7, float);
compare(u7, -float);
compare(u8, float);
compare(u8, -float);
compare(u9, float);
compare(u9, -float);
compare(i7, float);
compare(i7, -float);
compare(i8, float);
compare(i8, -float);
compare(i9, float);
compare(i9, -float);
compare(u11, float);
compare(u11, -float);
compare(u12, float);
compare(u12, -float);
compare(u13, float);
compare(u13, -float);
compare(i11, float);
compare(i11, -float);
compare(i12, float);
compare(i12, -float);
compare(i13, float);
compare(i13, -float);
const cur = timer.read();
if (cur - prev >= std.time.ns_per_s) {
std.log.info("i = {d}; float = {d}", .{ iterations, @as(i64, @intFromFloat(float)) });
prev = cur;
}
}
while (float < std.math.maxInt(i64)) : ({
iterations += 1;
float = std.math.nextAfter(f32, float, std.math.inf(f32));
}) {
compare(u7, float);
compare(u7, -float);
compare(u8, float);
compare(u8, -float);
compare(u9, float);
compare(u9, -float);
compare(i7, float);
compare(i7, -float);
compare(i8, float);
compare(i8, -float);
compare(i9, float);
compare(i9, -float);
compare(u11, float);
compare(u11, -float);
compare(u12, float);
compare(u12, -float);
compare(u13, float);
compare(u13, -float);
compare(i11, float);
compare(i11, -float);
compare(i12, float);
compare(i12, -float);
compare(i13, float);
compare(i13, -float);
const cur = timer.read();
if (cur - prev >= std.time.ns_per_s) {
std.log.info("i = {d}; float = {d}", .{ iterations, @as(i64, @intFromFloat(float)) });
prev = cur;
}
}
}
fn compare(comptime T: type, float: f32) void {
const int: i64 = @intFromFloat(float);
const from_int: T = truncateFromInt(T, int);
const from_float: T = truncateFromFloat(T, float);
if (from_int != from_float) {
std.log.err("result mismatch: T = {}; int = {d}, from_int = {d}, from_float = {d}", .{ T, int, from_int, from_float });
}
}
fn truncateFromInt(comptime T: type, x: anytype) T {
const UT = std.meta.Int(.unsigned, @bitSizeOf(T));
const UX = std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(x)));
return @bitCast(@as(UT, @truncate(@as(UX, @bitCast(x)))));
}
fn truncateFromFloat(comptime T: type, x: anytype) T {
const UT = std.meta.Int(.unsigned, @bitSizeOf(T));
const y: T = @bitCast(@as(UT, @intFromFloat(@rem(@abs(x), std.math.maxInt(UT) + 1))));
return if (x < 0) -%y else y;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment