Re: [PATCH] Implement "P0631R4 Math Constants" for C++20

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Implement "P0631R4 Math Constants" for C++20

Jonathan Wakely-3
On 31/07/19 19:07 +0200, Marc Glisse wrote:
>On Wed, 31 Jul 2019, Jonathan Wakely wrote:
>
>>The values of the constants are taken from Glibc where the equivalent
>>constant exists, or by rounding the actual constant to the same number
>>of digits as the Glibc constants have.
>
>How does it behave with __float128? I think that with -std=gnu++2a, it
>counts as a floating point type, but the constant first becomes a long
>double and thus loses precision.

Indeed it does:

#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
  template<>
    struct __is_floating_point_helper<__float128>
    : public true_type { };
#endif

We could add explicit specializations for __float128 and use the Q
suffix. That's not valid when __STRICT_ANSI__ is defined (unless
-fext-numeric-literals is also used) but as the snippet above shows,
__float128 isn't a floating-point type when __STRICT_ANSI__ is
defined.

So something like the attached patch.  The glibc <math.h> says the
values I used have enough digits for IEEE quad-precision:

/* The above constants are not adequate for computation using `long double's.
   Therefore we provide as an extension constants with similar names as a
   GNU extension.  Provide enough digits for the 128-bit IEEE quad.  */

I don't know if we need more accuracy for IBM double double.



patch.txt (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Implement "P0631R4 Math Constants" for C++20

Jakub Jelinek
On Wed, Jul 31, 2019 at 07:37:03PM +0100, Jonathan Wakely wrote:

> On 31/07/19 19:07 +0200, Marc Glisse wrote:
> > On Wed, 31 Jul 2019, Jonathan Wakely wrote:
> >
> > > The values of the constants are taken from Glibc where the equivalent
> > > constant exists, or by rounding the actual constant to the same number
> > > of digits as the Glibc constants have.
> >
> > How does it behave with __float128? I think that with -std=gnu++2a, it
> > counts as a floating point type, but the constant first becomes a long
> > double and thus loses precision.
>
> Indeed it does:
>
> #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
>  template<>
>    struct __is_floating_point_helper<__float128>
>    : public true_type { };
> #endif
>
> We could add explicit specializations for __float128 and use the Q
> suffix. That's not valid when __STRICT_ANSI__ is defined (unless
> -fext-numeric-literals is also used) but as the snippet above shows,
> __float128 isn't a floating-point type when __STRICT_ANSI__ is
> defined.

Perhaps add __extension__ before the literals too?

> I don't know if we need more accuracy for IBM double double.

I'd think the *L constants should be good enough.

        Jakub
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Implement "P0631R4 Math Constants" for C++20

Jonathan Wakely-3
On 31/07/19 20:50 +0200, Jakub Jelinek wrote:

>On Wed, Jul 31, 2019 at 07:37:03PM +0100, Jonathan Wakely wrote:
>> On 31/07/19 19:07 +0200, Marc Glisse wrote:
>> > On Wed, 31 Jul 2019, Jonathan Wakely wrote:
>> >
>> > > The values of the constants are taken from Glibc where the equivalent
>> > > constant exists, or by rounding the actual constant to the same number
>> > > of digits as the Glibc constants have.
>> >
>> > How does it behave with __float128? I think that with -std=gnu++2a, it
>> > counts as a floating point type, but the constant first becomes a long
>> > double and thus loses precision.
>>
>> Indeed it does:
>>
>> #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
>>  template<>
>>    struct __is_floating_point_helper<__float128>
>>    : public true_type { };
>> #endif
>>
>> We could add explicit specializations for __float128 and use the Q
>> suffix. That's not valid when __STRICT_ANSI__ is defined (unless
>> -fext-numeric-literals is also used) but as the snippet above shows,
>> __float128 isn't a floating-point type when __STRICT_ANSI__ is
>> defined.
>
>Perhaps add __extension__ before the literals too?

Does that do anything for Q literals? I thought I'd tried it
previously and decided it didn't. I'm happy to add it though.

>> I don't know if we need more accuracy for IBM double double.
>
>I'd think the *L constants should be good enough.

OK, great.


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Implement "P0631R4 Math Constants" for C++20

Segher Boessenkool
In reply to this post by Jonathan Wakely-3
On Wed, Jul 31, 2019 at 08:43:50PM +0200, Marc Glisse wrote:

> On Wed, 31 Jul 2019, Jonathan Wakely wrote:
>
> >So something like the attached patch.  The glibc <math.h> says the
> >values I used have enough digits for IEEE quad-precision:
> >
> >/* The above constants are not adequate for computation using `long
> >double's.
> > Therefore we provide as an extension constants with similar names as a
> > GNU extension.  Provide enough digits for the 128-bit IEEE quad.  */
> >
> >I don't know if we need more accuracy for IBM double double.
>
> double double has less precision than quad so it should be fine.

The *precision* (as defined in IEEE 754) of double double is much higher
than that of IEEE quad precision float: "the maximum number of
significant digits that can be represented in a format" -- it's just
that most of those bits have to be zero!

Neither double-double is a subset of QP, nor the other way around.  This
is *the* problem we have in rs6000 with these two float formats: GCC
cannot handle if two FP formats are like that.

(The math constants here are fine for double double, of course).


Segher
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Implement "P0631R4 Math Constants" for C++20

Jonathan Wakely-3
On 31/07/19 17:57 -0500, Segher Boessenkool wrote:

>On Wed, Jul 31, 2019 at 08:43:50PM +0200, Marc Glisse wrote:
>> On Wed, 31 Jul 2019, Jonathan Wakely wrote:
>>
>> >So something like the attached patch.  The glibc <math.h> says the
>> >values I used have enough digits for IEEE quad-precision:
>> >
>> >/* The above constants are not adequate for computation using `long
>> >double's.
>> > Therefore we provide as an extension constants with similar names as a
>> > GNU extension.  Provide enough digits for the 128-bit IEEE quad.  */
>> >
>> >I don't know if we need more accuracy for IBM double double.
>>
>> double double has less precision than quad so it should be fine.
>
>The *precision* (as defined in IEEE 754) of double double is much higher
>than that of IEEE quad precision float: "the maximum number of
>significant digits that can be represented in a format" -- it's just
>that most of those bits have to be zero!
>
>Neither double-double is a subset of QP, nor the other way around.  This
>is *the* problem we have in rs6000 with these two float formats: GCC
>cannot handle if two FP formats are like that.
>
>(The math constants here are fine for double double, of course).
Thanks. I've committed the attached patch then, after testing on
x86_64-linux and powerpc64le-linux.



patch.txt (4K) Download Attachment