[PATCH, V2] Add conversions between _Float128 and Decimal.

Segher Boessenkool segher@kernel.crashing.org
Sun Feb 21 00:33:12 GMT 2021


Hi!

On Tue, Feb 09, 2021 at 02:35:05AM -0500, Michael Meissner wrote:
> This patch implements conversions between _Float128 and the 3 Decimal floating
> types.  It does this by extendending the dfp-bit conversions to add a new
> binary floating point type (KF), and doing the conversions in the same manner
> as the other binary/decimal conversions.

> For conversions from _Float128 to Decimal, this patch uses a function
> (__sprintfkf) instead of the sprintf function to convert long double values to
> strings.  The __sprintfkf function determines if GLIBC 2.32 or newer is used
> and calls the IEEE 128-bit version of sprintf (__sprintfieee128).  If the GLIBC
> is earlier than 2.32, the code will convert _Float128 to __ibm128 and then use
> the normal sprintf to convert this value.

So if built with a glibc version before 2.32 (less than a year old) it
will give the wrong answer.  This needs improving, or it will be another
eight or so years until this is generally usable.

> The compilers built fine providing I recompiled gmp, mpc, and mpfr with the
> appropriate long double options.  There were a few differences in the test
> suite runs that will be addressed in later patches, but over all it works
> well.

What kind of differences?  I assume you checked all, and all differences
are an improvement, or the differences are inconsequential and the test
is not very good?

> --- /dev/null
> +++ b/libgcc/config/rs6000/_sprintfkf.c
> @@ -0,0 +1,57 @@
> +   If we are linked against an earlier library, we will have fake it by
> +   converting the value to long double, and using sprinf to do the conversion.

(typo, sprintf)

> +   This isn't ideal, as IEEE 128-bit has more exponent range than IBM
> +   128-bit.  */

And that results in some numbers being printed as Inf that are not.  But
also, the significand has more bits, so there is a loss of precision as
well.

> +int __sprintfkf (char *restrict string,
> +		 const char *restrict format,
> +		 _Float128 number)
> +{
> +  if (__sprintfieee128)
> +    return __sprintfieee128 (string, format, number);
> +
> +  return sprintf (string, format, (long double)number);

Space after cast.

> +_Float128
> +__strtokf (const char *string, char **endptr)
> +{
> +  long double num;
> +
> +  if (__strtoieee128)
> +    return __strtoieee128 (string, endptr);
> +
> +  num = strtold (string, endptr);
> +  return (_Float128) num;

Do not cast return values please.  All casts you do should be *needed*,
have a purpose.

> +  /* Use the sprintf library function to write the floating point value to a string.

Line too long.

Okay for trunk with those fixes.  Thanks!


Segher


More information about the Gcc-patches mailing list