https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119241

--- Comment #20 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #19)
> (In reply to Richard Biener from comment #18)
> > It's the following hunk.  real_to_decimal always uses e+exp notation
> > and a lower-case 'E'.
> 
> Not 100%.  I believe it prints -0.0 and 0.0 like that rather than -0.0e+00 or
> 0.0e+00, and when appending the e it can emit e+3 or e-2 rather than e+03
> and e-02
> that %e would emit.  Though, seems genapi.cc doesn't care about leading
> zeros in there,
> so maybe we just need to special case the 0/-0 cases and search for 'e'
> rather than 'E'.
> 
> >  So we might want to post-process the string
> > instead of trying to re-format.
> 
> And the %f case certainly needs more post processing, though perhaps that is
> not even enough, e.g. for very large E+NN numbers one might need much bigger
> precision.
> Though, the ach buffer is still just 128 bytes long, so perhaps it does that
> only for a subset of values.
> I wonder what happens when exp > 32, precision is negative, %.-17f wasn't
> really valid.

The following incremental patch correctly prints, the "weird part" is
the case of negative exponent, for positive I can simply shift the '.'

IDENTIFICATION DIVISION.
PROGRAM-ID. pass.
ENVIRONMENT DIVISION.
PROCEDURE DIVISION.
           DISPLAY -0.00012
           DISPLAY 0.00012
           DISPLAY 1234.66
           DISPLAY -99.8 
    STOP RUN.

diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
index 86ff3da2965..7f1b78dbf9a 100644
--- a/gcc/cobol/genapi.cc
+++ b/gcc/cobol/genapi.cc
@@ -4885,7 +4885,7 @@ parser_display_internal(tree file_descriptor,
     char ach[128];
     real_to_decimal (ach, TREE_REAL_CST_PTR (refer.field->data.value_of()),
                     sizeof(ach), 33, 0);
-    char *p = strchr(ach, 'E');
+    char *p = strchr(ach, 'e');
     if( !p )
       {
       // Probably INF -INF NAN or -NAN, so ach has our result
@@ -4898,11 +4898,27 @@ parser_display_internal(tree file_descriptor,
         {
         // We are going to stick with the E notation, so ach has our result
         }
-      else
+      else if (exp == 0)
+       {
+         p[-1] = '\0';
+       }
+      else if (exp < 0)
+        {
+         p[-1] = '\0';
+         char *q = strchr (ach, '.');
+         char dig = q[-1];
+         q[-1] = '\0';
+         char tem[128];
+         snprintf (tem, 128, "%s0.%0*u%c%s", ach, -exp - 1, 0, dig, q + 1);
+         strcpy (ach, tem);
+        }
+      else if (exp > 0)
         {
-        int precision = 32 - exp;
-       real_to_decimal (ach, TREE_REAL_CST_PTR (refer.field->data.value_of()),
-                        sizeof(ach), precision, 0);
+         p[-1] = '\0';
+         char *q = strchr (ach, '.');
+         for (int i = 0; i != exp; ++i)
+           q[i] = q[i + 1];
+         q[exp] = '.';
         }
       __gg__remove_trailing_zeroes(ach);
       }

Reply via email to