Comment by o11c
2 days ago
Note that there are a lot of exciting new float-related functions in C23, many related to NaN handling, signed zeros, or precision in edge cases. Some have been in glibc for years; others not yet.
The API for `getpayload`/`setpayload`/`setpayloadsig` looks a little funny but it's easy enough to wrap (just consider the edge cases; in particular remember that whether 0 is valid for quiet or signaling NaNs is platform-dependent).
Finally we have a reliable `roundeven`, and the convenience of directly calling `nextup`/`nextdown` (but note that you'll still only visit one of the zeros).
The new `fmaximum` family is confusing, but I think I have it clear:
without 'imum' (legacy): prefer non-NaN
with 'imum': zeros distinguished (-0 < +0)
with '_num': prefer a non-NaN, also signal if applicable
with '_mag': compare as if fabs first
`totalorder` has been often-desired; the other new comparisons not so much.
`rootn` and `compoundn` are surprisingly tricky to implement yourself. I still have one testcase I'm not sure why I have to hand-patch, and I'm not sure which implementation choice keeps the best precision (to say nothing of correct rounding mode).
> but note that you'll still only visit one of the zeros
Out of curiosity, isn't this what you'd pretty much universally want? Or maybe I misunderstand the intent here?
I find `nextup/`nextdown` useful for when you want to calculate `{f(nextdown(x)), f(x), f(nextup(x))}` and see if some property holds (or to what degree it holds) for both `x` and its surrounding values. It's annoying that one such surrounding value gets skipped.
That said, quite often you need to handle signed zero specially already, and if you don't the property you're testing might sufficiently differ in the interesting way for the smallest-magnitude subnormals.