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