[llvm] [APFloat] Add APFloat::format (PR #99088)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 8 00:28:52 PDT 2024


================
@@ -1378,6 +1378,171 @@ TEST(APFloatTest, toString) {
   }
 }
 
+TEST(APFloatTest, format) {
+  auto doit_precision = [](const fltSemantics &S, const char *value,
+                           llvm::FloatStyle style, int precision,
+                           const char *expected) {
+    SmallString<16> s;
+    APFloat apf(S, value);
+    apf.format(s, style, precision);
+    EXPECT_STREQ(expected, s.c_str());
+  };
+  auto doit = [](const fltSemantics &S, const char *value,
+                 llvm::FloatStyle style, const char *expected) {
+    SmallString<16> s;
+    APFloat apf(S, value);
+    apf.format(s, style);
+    EXPECT_STREQ(expected, s.c_str());
+  };
+
+  // default precision for Exponent and ExponentUpper is 6
+  // and 2 for Fixed and Psercent
+  // All float formats should be able to handle small vlues.
+  // The smaller formats, like float8, are more restricted.
+  for (unsigned I = 0; I != APFloat::S_MaxSemantics + 1; ++I) {
+    auto SemEnum = static_cast<APFloat::Semantics>(I);
+    const auto &S = APFloat::EnumToSemantics(SemEnum);
+    auto Precision = APFloat::semanticsPrecision(S);
+
+    // check 0
+    doit(S, "0.0", llvm::FloatStyle::Exponent, "0.000000e+00");
+    doit(S, "0.0", llvm::FloatStyle::ExponentUpper, "0.000000E+00");
+    doit(S, "0.0", llvm::FloatStyle::Fixed, "0.00");
+    doit(S, "0.0", llvm::FloatStyle::Percent, "0.00%");
+
+    // check that Exponent shifts left
+    doit(S, "0.5", llvm::FloatStyle::Exponent, "5.000000e-01");
+    doit(S, "0.5", llvm::FloatStyle::ExponentUpper, "5.000000E-01");
+    doit(S, "0.5", llvm::FloatStyle::Fixed, "0.50");
+    doit(S, "0.5", llvm::FloatStyle::Percent, "50.00%");
+
+    // check 1
+    doit(S, "1.0", llvm::FloatStyle::Exponent, "1.000000e+00");
+    doit(S, "1.0", llvm::FloatStyle::ExponentUpper, "1.000000E+00");
+    doit(S, "1.0", llvm::FloatStyle::Fixed, "1.00");
+    doit(S, "1.0", llvm::FloatStyle::Percent, "100.00%");
+
+    // check something with both an integer and a fraction
+    doit(S, "1.5", llvm::FloatStyle::Exponent, "1.500000e+00");
+    doit(S, "1.5", llvm::FloatStyle::ExponentUpper, "1.500000E+00");
+    doit(S, "1.5", llvm::FloatStyle::Fixed, "1.50");
+    doit(S, "1.5", llvm::FloatStyle::Percent, "150.00%");
+
+    // check negative
+    doit(S, "-1.5", llvm::FloatStyle::Exponent, "-1.500000e+00");
+    doit(S, "-1.5", llvm::FloatStyle::ExponentUpper, "-1.500000E+00");
+    doit(S, "-1.5", llvm::FloatStyle::Fixed, "-1.50");
+    doit(S, "-1.5", llvm::FloatStyle::Percent, "-150.00%");
+
+    // check rounding: 0
+    doit_precision(S, "0.0", llvm::FloatStyle::Exponent, 0, "0e+00");
+    doit_precision(S, "0.0", llvm::FloatStyle::ExponentUpper, 0, "0E+00");
+    doit_precision(S, "0.0", llvm::FloatStyle::Fixed, 0, "0");
+    doit_precision(S, "0.0", llvm::FloatStyle::Percent, 0, "0%");
+
+    // check round down
+    if (Precision >= 3) {
+      doit_precision(S, "1.25", llvm::FloatStyle::Exponent, 0, "1e+00");
+      doit_precision(S, "1.25", llvm::FloatStyle::ExponentUpper, 0, "1E+00");
+      doit_precision(S, "1.25", llvm::FloatStyle::Fixed, 0, "1");
+      doit_precision(S, "1.25", llvm::FloatStyle::Percent, 0, "125%");
+    }
+
+    // check round up
+    if (Precision >= 3) {
+      doit_precision(S, "1.25", llvm::FloatStyle::Exponent, 1, "1.3e+00");
+      doit_precision(S, "1.25", llvm::FloatStyle::ExponentUpper, 1, "1.3E+00");
+      doit_precision(S, "1.25", llvm::FloatStyle::Fixed, 1, "1.3");
+      doit_precision(S, "1.25", llvm::FloatStyle::Percent, 1, "125.0%");
+    }
+
+    // check round up to integer
+    if (Precision >= 3) {
+      doit_precision(S, "1.75", llvm::FloatStyle::Exponent, 0, "2e+00");
+      doit_precision(S, "1.75", llvm::FloatStyle::ExponentUpper, 0, "2E+00");
+      doit_precision(S, "1.75", llvm::FloatStyle::Fixed, 0, "2");
+      doit_precision(S, "1.75", llvm::FloatStyle::Percent, 0, "175%");
+    }
+
+    // check round up
+    if (Precision >= 3) {
+      doit_precision(S, "1.75", llvm::FloatStyle::Exponent, 1, "1.8e+00");
+      doit_precision(S, "1.75", llvm::FloatStyle::ExponentUpper, 1, "1.8E+00");
+      doit_precision(S, "1.75", llvm::FloatStyle::Fixed, 1, "1.8");
+      doit_precision(S, "1.75", llvm::FloatStyle::Percent, 1, "175.0%");
+    }
+
+    // check appending fewer than default number of zeros
+    if (Precision >= 3) {
+      doit_precision(S, "1.75", llvm::FloatStyle::Exponent, 3, "1.750e+00");
+      doit_precision(S, "1.75", llvm::FloatStyle::ExponentUpper, 3,
+                     "1.750E+00");
+      doit_precision(S, "1.75", llvm::FloatStyle::Fixed, 3, "1.750");
+      doit_precision(S, "1.75", llvm::FloatStyle::Percent, 3, "175.000%");
+    }
+
+    // check appending more than default number of zeros
+    if (Precision >= 3) {
+      doit_precision(S, "1.75", llvm::FloatStyle::Exponent, 8,
+                     "1.75000000e+00");
+      doit_precision(S, "1.75", llvm::FloatStyle::ExponentUpper, 8,
+                     "1.75000000E+00");
+      doit_precision(S, "1.75", llvm::FloatStyle::Fixed, 8, "1.75000000");
+      doit_precision(S, "1.75", llvm::FloatStyle::Percent, 8, "175.00000000%");
+    }
+  }
+
+  // test the main types with wider ranges
+  auto sems = {llvm::APFloat::S_IEEEsingle, llvm::APFloat::S_IEEEdouble,
+               llvm::APFloat::S_IEEEquad, llvm::APFloat::S_PPCDoubleDouble,
+               llvm::APFloat::S_x87DoubleExtended};
----------------
arsenm wrote:

Check the exotic cases, like the new type without zero 

https://github.com/llvm/llvm-project/pull/99088


More information about the llvm-commits mailing list