Skip to content

Commit 4991b82

Browse files
committed
Merge pull request #4337 from tsbockman/issue_16026
Fix issue 16026: std.math.frexp!float() wrong for very small subnormals
2 parents 7b08e86 + a6a1957 commit 4991b82

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

std/math.d

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,7 +2406,7 @@ T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc
24062406
vf *= F.RECIP_EPSILON;
24072407
ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
24082408
exp = ex - F.EXPBIAS - T.mant_dig + 1;
2409-
vu[F.EXPPOS_SHORT] = (0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE;
2409+
vu[F.EXPPOS_SHORT] = (~F.EXPMASK & vu[F.EXPPOS_SHORT]) | 0x3FFE;
24102410
}
24112411
return vf;
24122412
}
@@ -2449,7 +2449,7 @@ T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc
24492449
ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
24502450
exp = ex - F.EXPBIAS - T.mant_dig + 1;
24512451
vu[F.EXPPOS_SHORT] =
2452-
cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE);
2452+
cast(ushort)((~F.EXPMASK & vu[F.EXPPOS_SHORT]) | 0x3FFE);
24532453
}
24542454
return vf;
24552455
}
@@ -2489,7 +2489,7 @@ T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc
24892489
ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
24902490
exp = ((ex - F.EXPBIAS) >> 4) - T.mant_dig + 1;
24912491
vu[F.EXPPOS_SHORT] =
2492-
cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FE0);
2492+
cast(ushort)((~F.EXPMASK & vu[F.EXPPOS_SHORT]) | 0x3FE0);
24932493
}
24942494
return vf;
24952495
}
@@ -2529,7 +2529,7 @@ T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc
25292529
ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
25302530
exp = ((ex - F.EXPBIAS) >> 7) - T.mant_dig + 1;
25312531
vu[F.EXPPOS_SHORT] =
2532-
cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3F00);
2532+
cast(ushort)((~F.EXPMASK & vu[F.EXPPOS_SHORT]) | 0x3F00);
25332533
}
25342534
return vf;
25352535
}
@@ -2574,6 +2574,9 @@ unittest
25742574
tuple(-T.infinity, -T.infinity, int.min),
25752575
tuple(T.nan, T.nan, int.min),
25762576
tuple(-T.nan, -T.nan, int.min),
2577+
2578+
// Phobos issue #16026:
2579+
tuple(3 * (T.min_normal * T.epsilon), T( .75), (T.min_exp - T.mant_dig) + 2)
25772580
];
25782581

25792582
foreach (elem; vals)
@@ -2591,10 +2594,10 @@ unittest
25912594
static if (floatTraits!(T).realFormat == RealFormat.ieeeExtended)
25922595
{
25932596
static T[3][] extendedvals = [ // x,frexp,exp
2594-
[0x1.a5f1c2eb3fe4efp+73L, 0x1.A5F1C2EB3FE4EFp-1L, 74], // normal
2595-
[0x1.fa01712e8f0471ap-1064L, 0x1.fa01712e8f0471ap-1L, -1063],
2596-
[T.min_normal, .5, -16381],
2597-
[T.min_normal/2.0L, .5, -16382] // subnormal
2597+
[0x1.a5f1c2eb3fe4efp+73L, 0x1.A5F1C2EB3FE4EFp-1L, 74], // normal
2598+
[0x1.fa01712e8f0471ap-1064L, 0x1.fa01712e8f0471ap-1L, -1063],
2599+
[T.min_normal, .5, -16381],
2600+
[T.min_normal/2.0L, .5, -16382] // subnormal
25982601
];
25992602
foreach (elem; extendedvals)
26002603
{

0 commit comments

Comments
 (0)