C++ Logo

liaison

Advanced search

Re: [wg14/wg21 liaison] [isocpp-ext] Report from the recent C/C++ liaison meeting (SG22); includes new floating point types(!)

From: Aaron Ballman <compatibility.sg.chair_at_[hidden]>
Date: Fri, 17 Sep 2021 14:36:36 -0400
On Fri, Sep 17, 2021 at 2:03 PM Jorg Brown via Liaison
<liaison_at_[hidden]> wrote:
>
> I humbly suggest that before any meeting, there should be a list of important use cases that must be considered.

+1 -- if someone would like to suggest such a list for me to share
with interested parties across committees, that would be fantastic.

~Aaron

> For me, the one that comes to mind is:
>
> 1) I know of a few common FP scenarios:
>
> MSVC: float is 32-bit, double is 64-bit, long double is also 64-bit. (same for ARM64)
> x64 gcc/clang: float is 32-bit, double is 64-bit, long double is 80-bit.
> ARM64 gcc/clang: float is 32-bit, double is 64-bit, long double is 128-bit.
> Embedded with small FPU: all are 32-bit.
>
> My specific concern with the above is how overloads are handled. A function such as std::abs should be able to handle whatever standard C types_(Float16, _Float32, _Float64, etc) are built into the compiler. But since the standard library ships with the compiler, it also knows what macros it should use to detect support. As a library writer, I have a harder job: I have to handle all of these scenarios in a tooling-independent way.
>
> Already a huge problem is support for "long double": is it 128-bit or 80-bit or 64-bit? I can programmatically detect which of them a given type is, but I can't conditionally #include 128-bit support code unless there's a macro for that purpose, because "#if sizeof(double) == sizeof(long double)" doesn't compile.
>
> Something that would make me incredibly happy is if c++23 said that I could overload on std::float16, std::float32, std::float64, std::float80, and std::float128, and that the basic functions (+-*/, abs, frexp, ldexp) all work on those types, regardless of what the CPU natively supports. Alternatively, if there were macros I could check that would tell me if each of these had support - but it would still have to be guaranteed that "float", "long", and "long double" could be passed to my overload, without compile error.
>
> In Tony Table form:
>
> Currently:
>
> void Handle(float f) {
> if (std::numeric_limits<float>::digits == 24) return Handle_float32(f);
> if (std::numeric_limits<float>::digits == 53) return Handle_float64(f);
> }
> void Handle(double f) {
> if (std::numeric_limits<float>::digits == 24) return Handle_float32(f);
> if (std::numeric_limits<float>::digits == 53) return Handle_float64(f);
> }
> void Handle(long double f) {
> if (std::numeric_limits<float>::digits == 24) return Handle_float32(f);
> if (std::numeric_limits<float>::digits == 53) return Handle_float64(f);
> if (std::numeric_limits<float>::digits == 64) return Handle_float80(f);
> if (std::numeric_limits<float>::digits == 106) return Handle_float128(f);
> }
>
> My dream:
>
> #ifdef __cpp_float16
> void Handle(std::float16_t f);
> #endif
> #ifdef __cpp_float32
> void Handle(std::float32_t f);
> #endif
> #ifdef __cpp_float64
> void Handle(std::float64_t f);
> #endif
> #ifdef __cpp_float80
> void Handle(std::float80_t f);
> #endif
> #ifdef __cpp_float128
> void Handle(std::float128_t f);
> #endif
>
> = - = - = - =
>
> Looking at the actual details of http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1312.pdf , I find one thing new and intriguing: "Type-generic macros". Specifically, it says that if you include <tgmath.h>, you can write "pow(2, 3.0)" and get the double version of pow, and you can write "pow(2, 3.0DD)" and get the _Decimal64 version. This is of course common practice in C++, but how does C do this without overloads?
>
> Notably, the most glaring need for this is printf. If they are going to introduce a pow that does the right thing, how about a type-generic "tgprintf", that would automatically convert "%d" and "%u" to "%lld" and "%z" if the type of the parameters being passed were "long long" and "size_t"? (I'm hoping that the compiler would do this transformation, rather than some complicated runtime scheme)
>
> -- Jorg
>
> On Fri, Sep 17, 2021 at 4:57 AM Aaron Ballman via Ext <ext_at_[hidden]> wrote:
>>
>> On Fri, Sep 17, 2021 at 5:03 AM Matthias Kretz via Ext
>> <ext_at_[hidden]> wrote:
>> >
>> > On Friday, 17 September 2021 09:40:52 CEST Matthias Kretz via Ext wrote:
>> > > If those types have the same properties
>> > >
>> > > > (i.e. represent IEEE interchange types), they should be the
>> > > > same from a type system perspective.
>> > >
>> > > Do I read X.6 [2] correctly that all _Float* types must fully support NaN
>> > > and Inf? Whereas P1467 intends to leave NaN and Inf support implementation-
>> > > defined? Consequently, a feature like -ffinite-math-only would have to
>> > > disable Annex X support in the compiler / only apply to "standard floating
>> > > types"?
>> >
>> > I was a bit too fast...
>> >
>> > P1467 § 7.4. "Layout vs. behavior" says (emphasis mine):
>> > The IEEE-conforming type aliases must have the specified IEEE layout and
>> > *should have the required behavior*.
>> >
>> > Which seems to contradict § 5.1:
>> > It is currently implementation-defined whether or not the floating-point
>> > types support infinity and NaN. That is not changing. That feature will still
>> > be implementation-defined, even for extended floating-point types.
>> >
>> > Or I'm reading to much into the word "should". Why not remove the behavior
>> > requirement if all we're asking for is "should"?
>> >
>> > I'd be wary of asking for full IEC 60559 behavioral conformance for
>> > std::float*_t. Does this extend to <cmath>, i.e. require correctly rounded
>> > implementations of all cmath functions?
>> >
>> > FWIW, my strong opinion is that representation and behavior are two mostly
>> > orthogonal features of floating-point types and std::float*_t should only
>> > require IEC 60559 representation at this point. At some point we need to have
>> > a good talk about behavior and how to get back control over the fast-math
>> > optimizations we want and don't want compilers to perform. But that needs
>> > proper exploration.
>>
>> FWIW, it's sounding more and more to me like there's high risk for
>> user confusion and incompatibilities between C and C++ in this space
>> and we should consider a joint meeting with the C Floating Point Study
>> Group to see what can be done in both committees to reduce that
>> likelihood. I'm planning to discuss P1467 in SG22 on Oct 1, and I will
>> invite the CFP group (as well as others in WG14) to attend.
>>
>> ~Aaron
>>
>> >
>> > --
>> > ──────────────────────────────────────────────────────────────────────────
>> > Dr. Matthias Kretz https://mattkretz.github.io
>> > GSI Helmholtz Centre for Heavy Ion Research https://gsi.de
>> > stdₓ::simd
>> > ──────────────────────────────────────────────────────────────────────────
>> > _______________________________________________
>> > Ext mailing list
>> > Ext_at_[hidden]
>> > Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/ext
>> > Link to this post: http://lists.isocpp.org/ext/2021/09/17656.php
>> _______________________________________________
>> Ext mailing list
>> Ext_at_[hidden]
>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/ext
>> Link to this post: http://lists.isocpp.org/ext/2021/09/17657.php
>
> _______________________________________________
> Liaison mailing list
> Liaison_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> Link to this post: http://lists.isocpp.org/liaison/2021/09/0696.php

Received on 2021-09-17 13:36:53