[flang-commits] [flang] 4876520 - [flang] runtime: For Fw.d formatting, don't oscillate forever

peter klausler via flang-commits flang-commits at lists.llvm.org
Wed Aug 4 12:24:02 PDT 2021


Author: peter klausler
Date: 2021-08-04T12:19:23-07:00
New Revision: 4876520eef34f517075fed9007dc8b3162d67d1a

URL: https://github.com/llvm/llvm-project/commit/4876520eef34f517075fed9007dc8b3162d67d1a
DIFF: https://github.com/llvm/llvm-project/commit/4876520eef34f517075fed9007dc8b3162d67d1a.diff

LOG: [flang] runtime: For Fw.d formatting, don't oscillate forever

The algorithm for Fw.d output will drive binary to decimal conversion for
an initial fixed number of digits, then adjust that number based on the
result's exposent.  For value close to a power of ten, this adjustment
process wouldn't terminate; e.g., formatting 9.999 as F10.2 would start
with 1e2, boost the digits to 2, get 9.99e1, decrease the digits, and loop.
Solve by refusing to boost the digits a second time.

Differential Revision: https://reviews.llvm.org/D107490

Added: 
    

Modified: 
    flang/lib/Decimal/binary-to-decimal.cpp
    flang/runtime/edit-output.cpp
    flang/unittests/Runtime/NumericalFormatTest.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Decimal/binary-to-decimal.cpp b/flang/lib/Decimal/binary-to-decimal.cpp
index 68ee345b89352..c9efb3485798d 100644
--- a/flang/lib/Decimal/binary-to-decimal.cpp
+++ b/flang/lib/Decimal/binary-to-decimal.cpp
@@ -310,7 +310,6 @@ ConversionToDecimalResult ConvertToDecimal(char *buffer, std::size_t size,
         more.Next();
       }
       number.Minimize(Big{less, rounding}, Big{more, rounding});
-    } else {
     }
     return number.ConvertToDecimal(buffer, size, flags, digits);
   }

diff  --git a/flang/runtime/edit-output.cpp b/flang/runtime/edit-output.cpp
index 7a5130756d90a..38449671a1385 100644
--- a/flang/runtime/edit-output.cpp
+++ b/flang/runtime/edit-output.cpp
@@ -268,6 +268,7 @@ bool RealOutputEditing<binaryPrecision>::EditFOutput(const DataEdit &edit) {
   // Multiple conversions may be needed to get the right number of
   // effective rounded fractional digits.
   int extraDigits{0};
+  bool canIncrease{true};
   while (true) {
     decimal::ConversionToDecimalResult converted{
         Convert(extraDigits + fracDigits, edit, flags)};
@@ -277,11 +278,12 @@ bool RealOutputEditing<binaryPrecision>::EditFOutput(const DataEdit &edit) {
     }
     int scale{IsZero() ? 1 : edit.modes.scale}; // kP
     int expo{converted.decimalExponent + scale};
-    if (expo > extraDigits && extraDigits >= 0) {
+    if (expo > extraDigits && extraDigits >= 0 && canIncrease) {
       extraDigits = expo;
       if (!edit.digits.has_value()) { // F0
         fracDigits = sizeof buffer_ - extraDigits - 2; // sign & NUL
       }
+      canIncrease = false; // only once
       continue;
     } else if (expo < extraDigits && extraDigits > -fracDigits) {
       extraDigits = std::max(expo, -fracDigits);

diff  --git a/flang/unittests/Runtime/NumericalFormatTest.cpp b/flang/unittests/Runtime/NumericalFormatTest.cpp
index 470c2c6ce3bc7..746a4958f4288 100644
--- a/flang/unittests/Runtime/NumericalFormatTest.cpp
+++ b/flang/unittests/Runtime/NumericalFormatTest.cpp
@@ -627,6 +627,20 @@ TEST(IOApiTests, FormatDoubleValues) {
       {"(F5.3,';')", -0.0025, "-.003;"},
       {"(F5.3,';')", -0.00025, "-.000;"},
       {"(F5.3,';')", -0.000025, "-.000;"},
+      {"(F5.3,';')", 99.999, "*****;"},
+      {"(F5.3,';')", 9.9999, "*****;"},
+      {"(F5.3,';')", 0.99999, "1.000;"},
+      {"(F5.3,';')", 0.099999, "0.100;"},
+      {"(F5.3,';')", 0.0099999, "0.010;"},
+      {"(F5.3,';')", 0.00099999, "0.001;"},
+      {"(F5.3,';')", 0.000099999, "0.000;"},
+      {"(F5.3,';')", -99.999, "*****;"},
+      {"(F5.3,';')", -9.9999, "*****;"},
+      {"(F5.3,';')", -0.99999, "*****;"},
+      {"(F5.3,';')", -0.099999, "-.100;"},
+      {"(F5.3,';')", -0.0099999, "-.010;"},
+      {"(F5.3,';')", -0.00099999, "-.001;"},
+      {"(F5.3,';')", -0.000099999, "-.000;"},
   };
 
   for (auto const &[format, value, expect] : individualTestCases) {


        


More information about the flang-commits mailing list