It doesn't work. It's undefined behaviour. On NetBSD, it will fail
with EBADF, if fd 0 isn't open for write, or if fd 0 is open for
write, it will write heap garbage to fd 0.
If stream points to an output stream or an update stream in which
the most recent operation was not input, the fflush function causes
any unwritten data for that stream to be delivered to the host
environment to be written to the file; otherwise, the behavior is
undefined.
(ISO C11 and ISO C17, Sec. 7.21.5.2 `The fflush function')
PR lib/58206
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114879
Also add comments explaining how I generated these test cases.
(No autoconf back doors hidden in these magic numbers, I promise! No
pythagoreans were harmed in the production of these tests either.)
This test, to verify nexttoward(x, x*(1 - LDBL_EPSILON/2)) moves in
the direction of x*(1 - LDBL_EPSILON/2), only makes sense if long
double has more precision than double -- the point of the exercise is
to verify that nexttoward moves even if the direction parameter can't
be rounded to double. But if long double is just double, this test
makes no sense.
1. Need <math.h> for __HAVE_LONG_DOUBLE.
2. Need <machine/ieee.h> for struct ieee_ext_u &c.
3. EXT_FRACLBITS, not LDBL_MANL_SIZE.
PR lib/58245: hypotl is broken on ld128 ports
By this point in the logic, x can't be zero, so it's either positive
or negative.
The high word hx, however, can be zero, when x is a small positive
subnormal. This means x is a small positive subnormal, so if x > y
we are computing nextDown, and if x < y we are computing nextUp.
hx is a (signed 32-bit) integer, not a double floating-point number,
so it's a little silly to compare hx > 0.0. But that on its own
isn't enough to trigger the bug because all signed 32-bit integers
can be represented by double on all NetBSD architectures.
PR lib/58236
Noted by kre.
This doesn't break a passing test or fix a failed test, at least on
x86 -- our printf produces `0x1.533p+3' for the double case and
`0xa.99ap+0' for the long double case. But of the hexadecimal number
literals that that start with 0x5 having three hexadigits to the
right of the fractional point, 0x5.4cdp+1 closest to the IEEE 754
binary64, VAX D, x86 extended precision, and IEEE 754 binary128
floating-point numbers closest to 10.6.
The reason is that the number 10.6 (or the nearest floating-point
number in any format with enough precision) is:
101.0100 1100 1100|1100... * 2^1 = 0x5.4cc|c...p+1
If we round at the vertical bar to the _nearest_ output with three
hexadigits of precision, the result is:
101.0100 1100 1101 * 2^1 = 0x5.4cdp+1
LDBL_MAX is always defined, so this branch is dead. (If LDBL_MAX is
not defined, that's a bug in the architecture's float.h, not a reason
to skip a test.)
This reverts:
hdtoa.c 1.12 (PR/56247: Greg A. Woods: printf("%La", LDBL_MIN) dumps core)
hdtoa.c 1.11 (fix tyop)
hdtoa.c 1.10 (Via enh at google dot com in tech-userlevel. Fix handling of
EXT_FRAC{H,L}BITS (although we don't need to since we don't have them).)
The underlying motivation for this change was that when ld128 is
decomposed into 4x32 words, this hldtoa logic is broken.
But we don't decompose ld128 into 4x32 words; we decompose it into
6x64 words.
And the change, which was supposed to be a noop in our case of 2x64
words (or similar for x87 80-bit floating-point), broke it to the
point of causing buffer overruns (PR 56247) which when worked around
led to just incorrect output output (PR 56937).
If we want to make the #ifdefs for 4x32 words work, that's fine, but
we absolutely must have automatic test cases to detect this kind of
regression because %La formatting is extremely important for
diagnosing details of floating-point data since it doesn't involve
rounding in binary formats. For now I've added some trivial tests;
there is a more extensive test suite inside gdtoa that we need to
wire up before anyone tries any other shenanigans in this code.
PR lib/56937: printf(3) long double %a formatting is broken
1. Instead of calling out VAX by name, use #ifdef NAN and
isinf(INFINITY). (VAX defines INFINITY even though it's not an
infinity, not sure if there's a better compile-time test.)
2. Verify ilogbl works on long double on all architectures, not just
those with __HAVE_LONG_DOUBLE which means long double is _larger_
than double.
This one was adapted from the screw case shown in
https://mail-index.netbsd.org/tech-userlevel/2020/04/11/msg012329.html
which wasn't broken in our libc, but which nevertheless prompted us
to commit a wrong and apparently untested patch that has rendered
printf %La broken for the last four years, which is a little
embarrassing. (The part of that patch that led to a buffer overrun
has been worked around, so now the output is just incorrect.)
PR lib/56937: printf(3) long double %a formatting is broken
1. Instead of calling out VAX by name, use #ifdef NAN.
2. Verify signbit works on long double on all architectures, not just
those with __HAVE_LONG_DOUBLE which means long double is _larger_
than double.
3. Minor formatting tidying.
Conversion from uint64_t to long double should work on all ports,
including those where long double is the same as double, i.e., where
__HAVE_LONG_DOUBLE is undefined.
Instead, conditionalize the test cases on how many bits of precision
long double has in the significand, according to LDBL_MANT_DIG. The
conditionals here should handle binary128, powerpc double-dekker
(~106-bit precision), x86 extended precision (80-bit), m68k extended
precision (80-bit), and VAX D (56-bit).
If long double is the same as double, i.e., __HAVE_LONG_DOUBLE is
undefined, these tests should still pass, since they don't rely on
extra precision beyond double.
long double and LDBL_EPSILON work even on architectures where long
double is the same as double, i.e., where the confusingly named
__HAVE_LONG_DOUBLE is not defined.
cosl should always be defined even on architectures where long double
is the same as double so the confusingly named __HAVE_LONG_DOUBLE is
not defined.
__HAVE_LONG_DOUBLE just means long double is different from double.
This test should always pass on all ports, even if long double is the
same as double; it doesn't test any additional precision.