From a6a1957be301860b1fa5d9205f1edd7a39cc0a1a Mon Sep 17 00:00:00 2001 From: tsbockman Date: Wed, 18 May 2016 03:37:46 -0700 Subject: [PATCH] Fix issue 16026: std.math.frexp!float() wrong for very small subnormal values --- std/math.d | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/std/math.d b/std/math.d index d84c5edbe5e..f0fcc9f7f20 100644 --- a/std/math.d +++ b/std/math.d @@ -2406,7 +2406,7 @@ T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc vf *= F.RECIP_EPSILON; ex = vu[F.EXPPOS_SHORT] & F.EXPMASK; exp = ex - F.EXPBIAS - T.mant_dig + 1; - vu[F.EXPPOS_SHORT] = (0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE; + vu[F.EXPPOS_SHORT] = (~F.EXPMASK & vu[F.EXPPOS_SHORT]) | 0x3FFE; } return vf; } @@ -2449,7 +2449,7 @@ T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc ex = vu[F.EXPPOS_SHORT] & F.EXPMASK; exp = ex - F.EXPBIAS - T.mant_dig + 1; vu[F.EXPPOS_SHORT] = - cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE); + cast(ushort)((~F.EXPMASK & vu[F.EXPPOS_SHORT]) | 0x3FFE); } return vf; } @@ -2489,7 +2489,7 @@ T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc ex = vu[F.EXPPOS_SHORT] & F.EXPMASK; exp = ((ex - F.EXPBIAS) >> 4) - T.mant_dig + 1; vu[F.EXPPOS_SHORT] = - cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FE0); + cast(ushort)((~F.EXPMASK & vu[F.EXPPOS_SHORT]) | 0x3FE0); } return vf; } @@ -2529,7 +2529,7 @@ T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc 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); + cast(ushort)((~F.EXPMASK & vu[F.EXPPOS_SHORT]) | 0x3F00); } return vf; } @@ -2574,6 +2574,9 @@ unittest tuple(-T.infinity, -T.infinity, int.min), tuple(T.nan, T.nan, int.min), tuple(-T.nan, -T.nan, int.min), + + // Phobos issue #16026: + tuple(3 * (T.min_normal * T.epsilon), T( .75), (T.min_exp - T.mant_dig) + 2) ]; foreach (elem; vals) @@ -2591,10 +2594,10 @@ unittest static if (floatTraits!(T).realFormat == RealFormat.ieeeExtended) { static T[3][] extendedvals = [ // x,frexp,exp - [0x1.a5f1c2eb3fe4efp+73L, 0x1.A5F1C2EB3FE4EFp-1L, 74], // normal - [0x1.fa01712e8f0471ap-1064L, 0x1.fa01712e8f0471ap-1L, -1063], - [T.min_normal, .5, -16381], - [T.min_normal/2.0L, .5, -16382] // subnormal + [0x1.a5f1c2eb3fe4efp+73L, 0x1.A5F1C2EB3FE4EFp-1L, 74], // normal + [0x1.fa01712e8f0471ap-1064L, 0x1.fa01712e8f0471ap-1L, -1063], + [T.min_normal, .5, -16381], + [T.min_normal/2.0L, .5, -16382] // subnormal ]; foreach (elem; extendedvals) {