Hi!

I have still strong doubts that this parser_display_internal replacement
does what the code used to do before.

On Fri, Mar 21, 2025 at 01:56:40PM +0100, Richard Biener wrote:
> @@ -4884,8 +4883,9 @@ parser_display_internal(tree file_descriptor,
>      // We make use of that here
>  
>      char ach[128];
> -    strfromf128(ach, sizeof(ach), "%.33E", refer.field->data.value_of());
> -    char *p = strchr(ach, 'E');
> +    real_to_decimal (ach, TREE_REAL_CST_PTR (refer.field->data.value_of()),
> +                  sizeof(ach), 33, 0);
> +    char *p = strchr(ach, 'e');
>      if( !p )
>        {

I'd expect here something that deals with the 0.0 or -0.0 special cases,
those don't have 'e' in, and the end result should be "0" and "-0" I think.

>        // Probably INF -INF NAN or -NAN, so ach has our result
> @@ -4898,12 +4898,27 @@ parser_display_internal(tree file_descriptor,
>          {
>          // We are going to stick with the E notation, so ach has our result

I'd expect in this block something like
*p = 'E';
if (exp < 0 && exp >= -9)
  {
    p[1] = '-';
    p[2] = '0';
    p[3] = '0' - exp;
    p[4] = '\0';
  }
else if (exp >= 0 && exp <= 9)
  {
    p[1] = '+';
    p[2] = '0';
    p[3] = '0' + exp;
    p[4] = '\0';
  }
The old code used to print E rather than e and e.g. E+07 rather than e+7
or E-08 rather than e-8.

>          }
> -      else

and regarding the rest, I don't see how you can do it without another
real_from_decimal call.

Little demonstration on what the code I think does for the exp -4 to 5
inclusive:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

_Float128 t[] = {
  
1.22433121523574203224318071260646285216216731519578412502829653452609169052304e-4f128,
  
3.13808395492429316726284175623760992774106032377261471639338382211132077970101e-3f128,
  
5.26318403434216484244428445177075439411680945524413886546471660775380872427903e-2f128,
  
4.25323368284960119144795763181599180287388477575340264766231115475470878156674e-1f128,
  
9.11271133799960564330679918642859472808167031348520792920869161117023815641101e+0f128,
  
7.80516402565714651791537598303765273306642211227122109805454422948803989351485e+1f128,
  
2.80909185348047628488884628057549084123670902101497405229324029669706896917753e+2f128,
  
8.27614283782552989875908598504295559602004756864919830325249194046288881027419e+3f128,
  
6.32414643723336273776595135072909003628076160129418221323502781943365269207930e+4f128,
  
3.25049315012065586095487088465661503747374940888656416061674409595991039450196e+5f128
};

int
main ()
{
  for (int i = 0; i < 10; ++i)
    {
      char buf[128], buf2[24];
      strfromf128 (buf, sizeof (buf), "%.33E", t[i]);
      printf ("%s\n", buf);
      int p = 32 - (i - 4);
      sprintf (buf2, "%%.%df", p);
      strfromf128 (buf, sizeof (buf), buf2, t[i]);
      printf ("%s\n", buf);
    }
}

I think you need to repeat the call with:
    real_to_decimal (ach, TREE_REAL_CST_PTR (refer.field->data.value_of()),
                     sizeof(ach), 32, 0);
(32 instead of 33, so that it does proper rounding) and then do the decimal
point movements etc.  For all cases replace 'e' with '\0'.  For exp == 0 you're
done (well, still __gg__remove_trailing_zeroes(ach); should be done), for
exp < 0 start with "0." followed by 1 - exp '0's followed by digit before former
dot and the rest, for exp > 0 move the dot exp positions to the right:
1.224331215235742032243180712606463E-04
0.000122433121523574203224318071260646
3.138083954924293167262841756237610E-03
0.00313808395492429316726284175623761
5.263184034342164842444284451770754E-02
0.0526318403434216484244428445177075
4.253233682849601191447957631815992E-01
0.425323368284960119144795763181599
9.112711337999605643306799186428595E+00
9.11271133799960564330679918642860
7.805164025657146517915375983037653E+01
78.0516402565714651791537598303765
2.809091853480476284888846280575491E+02
280.909185348047628488884628057549
8.276142837825529898759085985042955E+03
8276.14283782552989875908598504296
6.324146437233362737765951350729090E+04
63241.4643723336273776595135072909
3.250493150120655860954870884656615E+05
325049.315012065586095487088465662

Rather than doing that with snprintf into another buffer plus strcpy, I'd
suggest just memmove.  I think the '.' char should be guaranteed on ach[1]
and 'e' should be at ach[35].
So
    real_to_decimal (ach, TREE_REAL_CST_PTR (refer.field->data.value_of()),
                     sizeof(ach), 32, 0);
    ach[35] = '\0';
    if (exp < 0)
      {
        memmove (ach + 2 - exp, ach + 2, 33);
        ach[1 - exp] = ach[0];
        ach[0] = '0';
        ach[1] = '.';
        memset (ach + 2, '0', -1 - exp);
      }
    else if (exp > 0)
      {
        memmove (ach + 1, ach + 2, exp);
        ach[exp + 1] = '.';
      }
or so.

        Jakub

Reply via email to