Prechádzať zdrojové kódy

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.
Matthew Olsson 4 rokov pred
rodič
commit
d719e745fb
2 zmenil súbory, kde vykonal 11 pridanie a 4 odobranie
  1. 5 4
      AK/Format.cpp
  2. 6 0
      AK/Tests/TestFormat.cpp

+ 5 - 4
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<i64>(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<u64>(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 <charconv>: Making Your Code 10x Faster With C++17's Final Boss”)
         value -= static_cast<i64>(value);
 
-        if (value < 0)
-            value = -value;
-
         double epsilon = 0.5;
         for (size_t i = 0; i < precision; ++i)
             epsilon /= 10.0;

+ 6 - 0
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<FlatPtr>(0)));