Serialize float options using the hexadecimal format

This ensures no information is lost when the value is round-tripped.
This commit is contained in:
Carl Åstholm 2025-03-24 13:22:08 +01:00
parent 5380e81924
commit e7604bba3e
2 changed files with 12 additions and 6 deletions

View file

@ -507,7 +507,7 @@ fn addUserInputOptionFromArg(
.comptime_float, .float => return if (maybe_value) |v| { .comptime_float, .float => return if (maybe_value) |v| {
map.put(field.name, .{ map.put(field.name, .{
.name = field.name, .name = field.name,
.value = .{ .scalar = std.fmt.allocPrint(arena, "{e}", .{v}) catch @panic("OOM") }, .value = .{ .scalar = std.fmt.allocPrint(arena, "{x}", .{v}) catch @panic("OOM") },
.used = false, .used = false,
}) catch @panic("OOM"); }) catch @panic("OOM");
}, },

View file

@ -1563,17 +1563,23 @@ pub fn printFloatHexOptions(w: *Writer, value: anytype, options: std.fmt.Number)
} }
pub fn printFloatHex(w: *Writer, value: anytype, case: std.fmt.Case, opt_precision: ?usize) Error!void { pub fn printFloatHex(w: *Writer, value: anytype, case: std.fmt.Case, opt_precision: ?usize) Error!void {
if (std.math.signbit(value)) try w.writeByte('-'); const v = switch (@TypeOf(value)) {
if (std.math.isNan(value)) return w.writeAll(switch (case) { // comptime_float internally is a f128; this preserves precision.
comptime_float => @as(f128, value),
else => value,
};
if (std.math.signbit(v)) try w.writeByte('-');
if (std.math.isNan(v)) return w.writeAll(switch (case) {
.lower => "nan", .lower => "nan",
.upper => "NAN", .upper => "NAN",
}); });
if (std.math.isInf(value)) return w.writeAll(switch (case) { if (std.math.isInf(v)) return w.writeAll(switch (case) {
.lower => "inf", .lower => "inf",
.upper => "INF", .upper => "INF",
}); });
const T = @TypeOf(value); const T = @TypeOf(v);
const TU = std.meta.Int(.unsigned, @bitSizeOf(T)); const TU = std.meta.Int(.unsigned, @bitSizeOf(T));
const mantissa_bits = std.math.floatMantissaBits(T); const mantissa_bits = std.math.floatMantissaBits(T);
@ -1583,7 +1589,7 @@ pub fn printFloatHex(w: *Writer, value: anytype, case: std.fmt.Case, opt_precisi
const exponent_mask = (1 << exponent_bits) - 1; const exponent_mask = (1 << exponent_bits) - 1;
const exponent_bias = (1 << (exponent_bits - 1)) - 1; const exponent_bias = (1 << (exponent_bits - 1)) - 1;
const as_bits: TU = @bitCast(value); const as_bits: TU = @bitCast(v);
var mantissa = as_bits & mantissa_mask; var mantissa = as_bits & mantissa_mask;
var exponent: i32 = @as(u16, @truncate((as_bits >> mantissa_bits) & exponent_mask)); var exponent: i32 = @as(u16, @truncate((as_bits >> mantissa_bits) & exponent_mask));