From ffcfeb919fc08724eea0346af8ea5531d62e2734 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Thu, 16 Apr 2026 04:53:07 +0200 Subject: [PATCH] Fix std.fmt.hex() to work with unsigned ints of all multiples of 8 bits @SizeOf(@typeInfo(T)) for any u{n} seems to give sizes of u32, u64, u128 and so on, depending on what size x fits into. This causes problems with '>>' if x isn't exactly one of those sizes. @typeInfo(@TypeOf(x)).int.bits gives a more accurate size. --- lib/std/fmt.zig | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index f8affb68b2..165b8fceb5 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -1342,9 +1342,9 @@ pub const hex_charset = "0123456789abcdef"; /// Converts an unsigned integer of any multiple of u8 to an array of lowercase /// hex bytes, little endian. -pub fn hex(x: anytype) [@sizeOf(@TypeOf(x)) * 2]u8 { +pub fn hex(x: anytype) [@typeInfo(@TypeOf(x)).int.bits / 4]u8 { comptime assert(@typeInfo(@TypeOf(x)).int.signedness == .unsigned); - var result: [@sizeOf(@TypeOf(x)) * 2]u8 = undefined; + var result: [@typeInfo(@TypeOf(x)).int.bits / 4]u8 = undefined; var i: usize = 0; while (i < result.len / 2) : (i += 1) { const byte: u8 = @truncate(x >> @intCast(8 * i)); @@ -1360,6 +1360,11 @@ test hex { try std.testing.expect(x.len == 8); try std.testing.expectEqualStrings("efbeadde", &x); } + { + const s = "[" ++ hex(@as(u48, 0x12345678_abcd)) ++ "]"; + try std.testing.expect(s.len == 14); + try std.testing.expectEqualStrings("[cdab78563412]", s); + } { const s = "[" ++ hex(@as(u64, 0x12345678_abcdef00)) ++ "]"; try std.testing.expect(s.len == 18);