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);
}