From 35c58f084e7cd79b51997439cff68346f4c724c0 Mon Sep 17 00:00:00 2001 From: Vladislav Shchapov Date: Fri, 9 Oct 2026 01:06:28 +0500 Subject: [PATCH] Fix hexfloat zero padding: zero padding must be placed after the sign and "0x" prefix (#4972) Signed-off-by: Vladislav Shchapov --- include/fmt/format.h | 21 +++++++++++++++++---- test/format-test.cc | 2 ++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 53cfdd73..4e6f320f 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3368,8 +3368,6 @@ FMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs, // Remove zero tail. while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits; - buf.push_back('0'); - buf.push_back(specs.upper() ? 'X' : 'x'); buf.push_back(xdigits[0]); if (specs.alt() || print_xdigits > 0 || print_xdigits < specs.precision) buf.push_back('.'); @@ -3745,9 +3743,24 @@ FMT_CONSTEXPR20 auto write(OutputIt out, T value, format_specs specs, memory_buffer buffer; if (specs.type() == presentation_type::hexfloat) { if (s != sign::none) buffer.push_back(detail::getsign(s)); + + size_t prefix_length = 0; + buffer.push_back('0'); + buffer.push_back(specs.upper() ? 'X' : 'x'); + if (specs.align() == align::numeric) { + prefix_length = buffer.size(); + const char* data = buffer.data(); + out = copy(data, data + prefix_length, out); + buffer.clear(); + } + format_hexfloat(convert_float(value), specs, buffer); - return write_bytes(out, {buffer.data(), buffer.size()}, - specs); + return write_padded( + out, specs, buffer.size(), buffer.size() + prefix_length, + [&buffer](reserve_iterator it) { + const char* data = buffer.data(); + return copy(data, data + buffer.size(), it); + }); } if (specs.type() == presentation_type::exp) { diff --git a/test/format-test.cc b/test/format-test.cc index a7b47d31..208a6c1a 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1671,6 +1671,8 @@ TEST(format_test, format_double) { EXPECT_EQ(fmt::format("{:L}", 42.0), "42"); EXPECT_EQ(fmt::format("{:24a}", 4.2f), " 0x1.0cccccp+2"); EXPECT_EQ(fmt::format("{:24a}", 4.2), " 0x1.0cccccccccccdp+2"); + EXPECT_EQ(fmt::format("{:012a}", 1.0), "0x0000001p+0"); + EXPECT_EQ(fmt::format("{:*>12a}", 1.0), "******0x1p+0"); EXPECT_EQ(fmt::format("{:<24a}", 4.2), "0x1.0cccccccccccdp+2 "); EXPECT_EQ(fmt::format("{0:e}", 392.65), "3.926500e+02"); EXPECT_EQ(fmt::format("{0:E}", 392.65), "3.926500E+02");