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

Peter Klausler via Phabricator via flang-commits flang-commits at lists.llvm.org
Wed Aug 4 11:17:48 PDT 2021


klausler created this revision.
klausler added a reviewer: PeteSteinfeld.
klausler added a project: Flang.
Herald added a subscriber: jdoerfert.
klausler requested review of this revision.

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 <https://reviews.llvm.org/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.


https://reviews.llvm.org/D107490

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


Index: flang/unittests/Runtime/NumericalFormatTest.cpp
===================================================================
--- flang/unittests/Runtime/NumericalFormatTest.cpp
+++ flang/unittests/Runtime/NumericalFormatTest.cpp
@@ -627,6 +627,20 @@
       {"(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) {
Index: flang/runtime/edit-output.cpp
===================================================================
--- flang/runtime/edit-output.cpp
+++ flang/runtime/edit-output.cpp
@@ -268,6 +268,7 @@
   // 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 @@
     }
     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);
Index: flang/lib/Decimal/binary-to-decimal.cpp
===================================================================
--- flang/lib/Decimal/binary-to-decimal.cpp
+++ flang/lib/Decimal/binary-to-decimal.cpp
@@ -310,7 +310,6 @@
         more.Next();
       }
       number.Minimize(Big{less, rounding}, Big{more, rounding});
-    } else {
     }
     return number.ConvertToDecimal(buffer, size, flags, digits);
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D107490.364199.patch
Type: text/x-patch
Size: 2535 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20210804/d3d64edf/attachment-0001.bin>


More information about the flang-commits mailing list