[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