commit ffcfeb919fc08724eea0346af8ea5531d62e2734 (tree)
parent 29532177c1c03a20d011e794f9abb70f1bdb6d59
Author: Richard Levitte <richard@levitte.org>
Date: Thu, 16 Apr 2026 04:53:07 +0200
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.
Diffstat:
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git 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));
@@ -1361,6 +1361,11 @@ test hex {
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);
try std.testing.expectEqualStrings("[00efcdab78563412]", s);