[Issue 16026] std.math.frexp!float() wrong for very small subnormal values

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Wed May 18 03:05:44 PDT 2016


--- Comment #4 from thomas.bockman at gmail.com ---
> Maybe you're bit twiddling the float differently then.

Ah! I found it:

    // float subnormal
    vf *= F.RECIP_EPSILON;
    ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
    exp = ((ex - F.EXPBIAS) >> 7) - T.mant_dig + 1;
    vu[F.EXPPOS_SHORT] =
        cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3F00);

Above, the 0x8000 should really be ~F.EXPMASK, because the fractional part
overlaps with the highest 16 bits, where the exponent and sign are. The double
version has the same problem. I bet it got copy-pasta-ed from the 80-bit and
128-bit code, where 0x8000 == ~F.EXPMASK.

I could submit a quick two-line fix, but I'd rather actually clean up all those
"magic numbers" and the copy-pasta: https://github.com/dlang/phobos/pull/4336

If PR #4336 gets accepted, I can just replace the whole frexp() implementation
with something more maintainable. (I already have it working; but need to add
ibmExtended support.)


More information about the Digitalmars-d-bugs mailing list