From 053b02eb33e49c87845fd61d38f99771c6d4fcd6 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Thu, 15 Feb 2018 20:34:34 +0100 Subject: [PATCH] [ltsmaster] std.math: Fix frexp() for 128 bit reals by aligning EXPBIAS with other formats Backport of https://github.com/dlang/phobos/pull/5445 --- std/math.d | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/std/math.d b/std/math.d index 3b6d161acba..c82acdd1175 100644 --- a/std/math.d +++ b/std/math.d @@ -265,6 +265,7 @@ template floatTraits(T) { // EXPMASK is a ushort mask to select the exponent portion (without sign) // EXPSHIFT is the number of bits the exponent is left-shifted by in its ushort + // EXPBIAS is the exponent bias - 1 (exp == EXPBIAS yields ×2^-1). // EXPPOS_SHORT is the index of the exponent when represented as a ushort array. // SIGNPOS_BYTE is the index of the sign when represented as a ubyte array. // RECIP_EPSILON is the value such that (smallest_subnormal) * RECIP_EPSILON == T.min_normal @@ -355,7 +356,7 @@ template floatTraits(T) // Quadruple precision float enum ushort EXPMASK = 0x7FFF; enum ushort EXPSHIFT = 0; - enum ushort EXPBIAS = 0x3FFF; + enum ushort EXPBIAS = 0x3FFE; enum realFormat = RealFormat.ieeeQuadruple; version(LittleEndian) { @@ -2500,9 +2501,10 @@ T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc if (ex) // If exponent is non-zero { if (ex == F.EXPMASK) - { // infinity or NaN + { + // infinity or NaN if (vl[MANTISSA_LSB] | - ( vl[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF)) // NaN + (vl[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF)) // NaN { // convert NaNS to NaNQ vl[MANTISSA_MSB] |= 0x0000_8000_0000_0000; @@ -2512,17 +2514,15 @@ T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc exp = int.min; else // positive infinity exp = int.max; - } else { exp = ex - F.EXPBIAS; - vu[F.EXPPOS_SHORT] = - cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE); + vu[F.EXPPOS_SHORT] = F.EXPBIAS | (0x8000 & vu[F.EXPPOS_SHORT]); } } - else if ((vl[MANTISSA_LSB] - |(vl[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF)) == 0) + else if ((vl[MANTISSA_LSB] | + (vl[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF)) == 0) { // vf is +-0.0 exp = 0; @@ -2533,8 +2533,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] = - cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE); + vu[F.EXPPOS_SHORT] = F.EXPBIAS | (0x8000 & vu[F.EXPPOS_SHORT]); } return vf; }