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

Reply via email to