From 90513adca146f18c6d6223a5b48633da109d4ca4 Mon Sep 17 00:00:00 2001 From: Sahana Bogar Date: Wed, 14 Oct 2026 23:46:38 +0530 Subject: [PATCH 1/2] Avoid right-shifting a negative value in detail::power() --- include/fast_float/decimal_to_binary.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/fast_float/decimal_to_binary.h b/include/fast_float/decimal_to_binary.h index 5389701..0dbc995 100644 --- a/include/fast_float/decimal_to_binary.h +++ b/include/fast_float/decimal_to_binary.h @@ -61,9 +61,15 @@ namespace detail { * -ceil(p) + q * where * p = log(5**-q)/log(2) = -q * log(5)/log(2) + * + * The shift must floor towards negative infinity, as an arithmetic right + * shift does, but right-shifting a negative value is implementation-defined + * before C++20. Biasing the product by 2048 * 65536 keeps the shifted value + * non-negative without changing the result: the bias is a multiple of 2^16 + * and is removed again after the shift. */ constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept { - return (((152170 + 65536) * q) >> 16) + 63; + return (((152170 + 65536) * q + (2048 * 65536)) >> 16) - 2048 + 63; } } // namespace detail From 0de7a21da582b6c84b0546772a96549882905d2b Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Sat, 17 Oct 2026 08:55:50 -0400 Subject: [PATCH 2/2] Run clang-format --- tests/fixedwidthtest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fixedwidthtest.cpp b/tests/fixedwidthtest.cpp index e7dabe7..0eebd24 100644 --- a/tests/fixedwidthtest.cpp +++ b/tests/fixedwidthtest.cpp @@ -14,8 +14,8 @@ // If no characters match the pattern, value must be left unmodified // (see https://github.com/fastfloat/fast_float/issues/424). template bool check_invalid_input_preserves_value() { - std::vector const invalid_inputs{"x", "", "-", ".", "e1", - "-x", "na", "+"}; + std::vector const invalid_inputs{"x", "", "-", ".", + "e1", "-x", "na", "+"}; for (auto const &f : invalid_inputs) { T result = T(42); auto answer = fast_float::from_chars(f.data(), f.data() + f.size(), result);