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: Jorg Brown <jorg.brown_at_[hidden]>
Date: Fri, 17 Sep 2021 11:03:11 -0700
I humbly suggest that before any meeting, there should be a list of
important use cases that must be considered. 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
>

Received on 2021-09-17 13:03:29