On Mon, 13 Sep 2021, Patrick Northon wrote:
Looks like a bug in glibc to me. I think I narrowed it down to where and what
in their code but I don't know why it's coded that way. I don't think it's
well tested, I don't think anybody ever use that particular case in real
software.
After looking at glibc's implementation, I also noticed that the rounding is
affected by the rounding mode. Right now in mingw, it's only rounding to
nearest. I don't know how it is on other platforms.
Oh right, different rounding directions might the cause for this. It seems
like the issue only happens for the value exactly inbetween, which is the
only value affected by the rounding direction.
The same also happens for digits in other places. E.g.:
union {
double f;
uint64_t i;
} u = { .i = 0x0008000000000000ULL };
printf("%a\n", u.f);
printf("%.0a\n", u.f);
u.i = 0x0000800000000000ULL;
printf("%a\n", u.f);
printf("%.1a\n", u.f);
Prints this with glibc:
0x0.8p-1022
0x0p-1022
0x0.08p-1022
0x0.0p-1022
But if I put a 1 in the lowest bit of the mantissa, which shouldn't affect
the rounding at all (in our implementation), I get this:
0x0.8000000000001p-1022
0x1p-1022
0x0.0800000000001p-1022
0x0.1p-1022
I.e. as long as our implementation doesn't bother with implementing
different rounding directions for this function, your patch should be
fine - thus I pushed it.
I noticed that our conversion from 64 bit float to the 80 bit struct used
for formatting didn't handle denormals correctly though, so I sent a
separate patch to fix that. With that, the output seems correct for
denormals too, on arm64.
// Martin
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public