From d719e745fbbcf7f66f3b4d9938772c4120f6e533 Mon Sep 17 00:00:00 2001 From: Matthew Olsson Date: Thu, 15 Apr 2021 13:28:02 -0700 Subject: [PATCH] AK: Fix incorrect formatter signing of numbers between -1.0 and 0.0 Floating point numbers are casted to i64 and passed to the integer formatting logic, and the floating point portion of the number is handled separately. However, casting to i64 when the number is between -1.0 and 0.0 produces 0, so the sign would be lost. This commit fixes that by using put_u64 instead, which allows us to manually provide the is_negative flag. --- AK/Format.cpp | 9 +++++---- AK/Tests/TestFormat.cpp | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/AK/Format.cpp b/AK/Format.cpp index 0fe6f06a2b..e9c56489a7 100644 --- a/AK/Format.cpp +++ b/AK/Format.cpp @@ -390,7 +390,11 @@ void FormatBuilder::put_f64( StringBuilder string_builder; FormatBuilder format_builder { string_builder }; - format_builder.put_i64(static_cast(value), base, false, upper_case, false, Align::Right, 0, ' ', sign_mode); + bool is_negative = value < 0.0; + if (is_negative) + value = -value; + + format_builder.put_u64(static_cast(value), base, false, upper_case, false, Align::Right, 0, ' ', sign_mode, is_negative); if (precision > 0) { // FIXME: This is a terrible approximation but doing it properly would be a lot of work. If someone is up for that, a good @@ -398,9 +402,6 @@ void FormatBuilder::put_f64( // https://youtu.be/4P_kbF0EbZM (Stephan T. Lavavej “Floating-Point : Making Your Code 10x Faster With C++17's Final Boss”) value -= static_cast(value); - if (value < 0) - value = -value; - double epsilon = 0.5; for (size_t i = 0; i < precision; ++i) epsilon /= 10.0; diff --git a/AK/Tests/TestFormat.cpp b/AK/Tests/TestFormat.cpp index 6ee5b8ed55..2a9a15762c 100644 --- a/AK/Tests/TestFormat.cpp +++ b/AK/Tests/TestFormat.cpp @@ -273,6 +273,12 @@ TEST_CASE(yay_this_implementation_sucks) EXPECT_EQ(String::formatted("{:.0}", .99999999999), "0"); } +TEST_CASE(magnitude_less_than_zero) +{ + EXPECT_EQ(String::formatted("{}", -0.654), "-0.654"); + EXPECT_EQ(String::formatted("{}", 0.654), "0.654"); +} + TEST_CASE(format_nullptr) { EXPECT_EQ(String::formatted("{}", nullptr), String::formatted("{:p}", static_cast(0)));