https://issues.dlang.org/show_bug.cgi?id=16026
--- Comment #4 from thomas.bock...@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.) --