From b2b9b074d4de754e533b2c9aae681155f1452859 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 7 Nov 2026 12:48:37 -0800 Subject: [PATCH] Simplify hexfloat rounding and test long double ties Avoids shifting by zero, which is undefined for the fallback uint128. The float tie test duplicated the double one; floats format as doubles. --- include/fmt/format.h | 14 +++----------- test/format-test.cc | 3 ++- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 7ccd2911..87fce444 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3366,18 +3366,10 @@ FMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs, int print_xdigits = num_xdigits - 1; if (specs.precision >= 0 && print_xdigits > specs.precision) { - const int shift = ((print_xdigits - specs.precision - 1) * 4); - const auto mask = carrier_uint(0xF) << shift; - const auto v = static_cast((f.f & mask) >> shift); + const int shift = (print_xdigits - specs.precision) * 4; + const auto inc = carrier_uint(1) << shift; // Round half to even like printf. - const bool odd = ((f.f >> (shift + 4)) & 1) != 0; - const bool rest_is_zero = (f.f & ((carrier_uint(1) << shift) - 1)) == 0; - - if (v > 8 || (v == 8 && (odd || !rest_is_zero))) { - const auto inc = carrier_uint(1) << (shift + 4); - f.f += inc; - f.f &= ~(inc - 1); - } + f.f += (inc >> 1) - 1 + ((f.f >> shift) & 1); // Check long double overflow. if (!has_implicit_bit()) { diff --git a/test/format-test.cc b/test/format-test.cc index e1d6d204..b99c7a79 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1756,7 +1756,8 @@ TEST(format_test, format_double) { EXPECT_EQ(fmt::format("{:.1a}", 1.03125), "0x1.0p+0"); EXPECT_EQ(fmt::format("{:.1a}", 1.09375), "0x1.2p+0"); EXPECT_EQ(fmt::format("{:.1a}", 1.0322265625), "0x1.1p+0"); - EXPECT_EQ(fmt::format("{:.1A}", 1.03125f), "0X1.0P+0"); + if (std::numeric_limits::digits == 64) + EXPECT_EQ(fmt::format("{:.0a}", 1.0625l), "0x8p-3"); EXPECT_EQ(fmt::format("{:a}", -42.0), "-0x1.5p+5"); EXPECT_EQ(fmt::format("{:A}", -42.0), "-0X1.5P+5");