Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Changeset 3180

Show
Ignore:
Timestamp:
02/14/08 03:20:22 (10 months ago)
Author:
Don Clugston
Message:

More fixes for quadruple reals. In particular, ieeeMean was horribly broken.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/tango/math/IEEE.d

    r3177 r3180  
    229229            INVALID_MASK   = 0xF80 
    230230        } 
     231    } else { //SPARC -- not yet implemented 
     232        enum : int { 
     233            INEXACT_MASK   = 0, 
     234            UNDERFLOW_MASK = 0, 
     235            OVERFLOW_MASK  = 0, 
     236            DIVBYZERO_MASK = 0, 
     237            INVALID_MASK   = 0 
     238        } 
    231239    } 
    232240private: 
     
    444452        vu[EXPONENTPOS_SHORT] = cast(ushort)((0x8000 & vu[EXPONENTPOS_SHORT]) | 0x3FFE); 
    445453    } 
    446   } else static if (real.mant_dig == 113) { 
    447       // quadruple       
     454  } else static if (real.mant_dig == 113) { // quadruple       
    448455        if (ex) { // If exponent is non-zero 
    449456            if (ex == EXPMASK) {   // infinity or NaN 
     
    470477            // multi-byte left shift 
    471478            vl[1]<<=1; 
    472             if (*v1<0) ++vl[1]; 
     479            if (*vl<0) ++vl[1]; 
    473480            *vl <<= 1; 
    474481        } while ((vl[1]&0x0000_8000_0000_0000)== 0); 
     
    476483        vu[EXPONENTPOS_SHORT] = cast(ushort)((0x8000 & vu[EXPONENTPOS_SHORT]) | 0x3FFE); 
    477484    } 
    478   } else static if(real.mant_dig==106) { // doubledouble 
    479         assert(0, "Unsupported"); 
    480   } else {    // 64-bit reals 
     485  } else static if (real.mant_dig==53) { // real is double 
    481486    if (ex) { // If exponent is non-zero 
    482487        if (ex == EXPMASK) {   // infinity or NaN 
     
    510515        ve[EXPONENTPOS_SHORT] = sgn; 
    511516    } 
     517  }else { //static if(real.mant_dig==106) // doubledouble 
     518        assert(0, "Unsupported"); 
    512519  } 
    513520    return value; 
     
    737744        } 
    738745    } else { 
    739         // BUG: Not implemented in DMD 
     746        // NOTE: Not implemented in DMD 
    740747        return tango.stdc.math.scalbnl(x, n); 
    741748    } 
     
    903910    ushort *p = cast(ushort *)&d; 
    904911    version(LittleEndian) { 
    905         uint e = p[3] & 0x7FF0; 
     912        ushort e = p[3] & 0x7FF0; 
    906913    } else { 
    907         uint e = p[0] & 0x7FF0; 
     914        ushort e = p[0] & 0x7FF0; 
    908915    } 
    909916    return e!=0 && e != 0x7FF0; 
     
    10091016    uint *p = cast(uint *)&f; 
    10101017 
    1011     return (*p & 0x7F800000) == 0 && *p & 0x007FFFFF; 
     1018    return (*p & 0x7F80_0000) == 0 && *p & 0x007F_FFFF; 
    10121019} 
    10131020 
     
    10281035    uint *p = cast(uint *)&d; 
    10291036 
    1030     return (p[1] & 0x7FF00000) == 0 && (p[0] || p[1] & 0x000FFFFF); 
     1037    version(LittleEndian) { 
     1038        return (p[1] & 0x7FF0_0000) == 0 && (p[0] || p[1] & 0x000F_FFFF); 
     1039    } else { 
     1040        return (p[0] & 0x7FF0_0000) == 0 && (p[1] || p[0] & 0x000F_FFFF); 
     1041    } 
    10311042} 
    10321043 
     
    10771088        return ((*cast(ulong *)&x) & 0x7FFF_FFFF_FFFF_FFFF) == 0; 
    10781089    } else static if (real.mant_dig == 113) { // quadruple    
    1079         long*   ps = cast(long *)&e
    1080             return (ps[MANTISSA_LSB]==0 || (ps[MANTISSA_MSB]& 0x7FFF_FFFF_FFFF_FFFF) == 0)
     1090        long*   ps = cast(long *)&x
     1091        return (ps[MANTISSA_LSB] | (ps[MANTISSA_MSB]& 0x7FFF_FFFF_FFFF_FFFF)) == 0
    10811092    } else { // real80 
    10821093        ushort* pe = cast(ushort *)&x; 
     
    14691480    // they could have 0 or 1 bits in common. 
    14701481 
    1471  static if (real.mant_dig==64 || real.mant_dig==113) { // real64 
     1482 static if (real.mant_dig==64 || real.mant_dig==113) { // real80 or quadruple 
    14721483    int bitsdiff = ( ((pa[EXPONENTPOS_SHORT]&0x7FFF) + (pb[EXPONENTPOS_SHORT]&0x7FFF)-1)>>1) - pd[EXPONENTPOS_SHORT]; 
    14731484 
     
    14861497    // Avoid out-by-1 errors when factor is almost 2. 
    14871498    return (bitsdiff == 0) ? (pa[EXPONENTPOS_SHORT] == pb[EXPONENTPOS_SHORT]) : 0; 
    1488  } else static if(real.mant_dig==106) { // doubledouble 
    1489         assert(0, "Unsupported"); 
    1490  } else { // real64 
     1499 } else static if(real.mant_dig==53) { // real is double 
    14911500    int bitsdiff = (( ((pa[EXPONENTPOS_SHORT]&0x7FF0) + (pb[EXPONENTPOS_SHORT]&0x7FF0)-0x10)>>1)  
    14921501                 - (pd[EXPONENTPOS_SHORT]&0x7FF0))>>4; 
     
    15071516    if (bitsdiff == 0 && !((pa[EXPONENTPOS_SHORT] ^ pb[EXPONENTPOS_SHORT])&EXPMASK)) return 1; 
    15081517    else return 0; 
    1509  } 
    1510  
     1518 } else { //static if(real.mant_dig==106) { // doubledouble 
     1519        assert(0, "Unsupported"); 
     1520 }  
    15111521} 
    15121522 
     
    16441654 
    16451655    T u; 
    1646     static if (T.mant_dig==64) { // x87, 80-bit reals 
     1656    static if (T.mant_dig==64) { // real80 
    16471657        // There's slight additional complexity because they are actually 
    16481658        // 79-bit reals... 
     
    16531663        ushort *ye = cast(ushort *)&y; 
    16541664        ulong *yl = cast(ulong *)&y; 
    1655         // Ignore the useless implicit bit. 
     1665        // Ignore the useless implicit bit. (Bonus: this prevents overflows) 
    16561666        ulong m = ((*xl) & 0x7FFF_FFFF_FFFF_FFFF) + ((*yl) & 0x7FFF_FFFF_FFFF_FFFF); 
    16571667 
     
    16741684        ulong *xl = cast(ulong *)&x; 
    16751685        ulong *yl = cast(ulong *)&y; 
    1676         ulong m = (((*xl) & 0x7FFF_FFFF_FFFF_FFFF) + ((*yl) & 0x7FFF_FFFF_FFFF_FFFF)) >>> 1; 
    1677         m |= ((*xl) & 0x8000_0000_0000_0000); 
    1678         *ul = m;            
     1686        // Multi-byte add, then multi-byte right shift.         
     1687        ulong mh = ((xl[MANTISSA_MSB] & 0x7FFF_FFFF_FFFF_FFFF) + (yl[MANTISSA_MSB] & 0x7FFF_FFFF_FFFF_FFFF)); 
     1688        ulong ml = (xl[MANTISSA_LSB]>>>1) + (yl[MANTISSA_LSB]>>>1);         
     1689        if (xl[MANTISSA_LSB] & yl[MANTISSA_LSB]) { 
     1690            ++ml; 
     1691            if (ml==0) ++mh; 
     1692        } 
     1693        mh >>>=1; 
     1694        ul[MANTISSA_MSB] = mh | (xl[MANTISSA_MSB] & 0x8000_0000_0000_0000); 
     1695        ul[MANTISSA_LSB] = ml; 
    16791696    } else static if (T.mant_dig == double.mant_dig) { 
    16801697        ulong *ul = cast(ulong *)&u; 
     
    16841701        m |= ((*xl) & 0x8000_0000_0000_0000); 
    16851702        *ul = m; 
    1686     }else static if (T.mant_dig == float.mant_dig) { 
     1703    } else static if (T.mant_dig == float.mant_dig) { 
    16871704        uint *ul = cast(uint *)&u; 
    16881705        uint *xl = cast(uint *)&x; 
     
    16911708        m |= ((*xl) & 0x8000_0000); 
    16921709        *ul = m; 
     1710    } else { 
     1711        assert(0, "Not implemented"); 
    16931712    } 
    16941713    return u; 
     
    17321751real NaN(ulong payload) 
    17331752{ 
    1734     static if (real.mant_dig == 53) { 
     1753    static if (real.mant_dig == 64) { //real80 
     1754      ulong v = 3; // implied bit = 1, quiet bit = 1 
     1755    } else { 
    17351756      ulong v = 2; // no implied bit. quiet bit = 1 
    1736     } else { 
    1737       ulong v = 3; // implied bit = 1, quiet bit = 1 
    17381757    } 
    17391758