home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / xldscale.c < prev    next >
C/C++ Source or Header  |  1998-06-16  |  4KB  |  143 lines

  1. /* _LDscale function -- IEEE 754 version */
  2. #include "wctype.h"
  3. #include "xmath.h"
  4. _STD_BEGIN
  5.  
  6. #if !_DLONG
  7. _CRTIMP2 short _LDscale(long double *px, long lexp)
  8.     {    /* scale *px by 2^lexp with checking */
  9.     return (_Dscale((double *)px, lexp));
  10.     }
  11. #elif _LONG_DOUBLE_HAS_HIDDEN_BIT
  12. _CRTIMP2 short _LDscale(long double *px, long lexp)
  13.     {    /* scale *px by 2^lexp with checking -- SPARC */
  14.     unsigned short *ps = (unsigned short *)px;
  15.     unsigned short frac;
  16.     short xchar = ps[_L0] & _LMASK;
  17.  
  18.     if (xchar == _LMAX)
  19.         return (ps[_L1] != 0 || ps[_L2] != 0 || ps[_L3] != 0
  20.             || ps[_L4] != 0 || ps[_L5] != 0 || ps[_L6] != 0
  21.             || ps[_L7] != 0 ? NAN : INF);
  22.     else if (xchar == 0 && 0 < (xchar = _LDnorm(ps)))
  23.         return (0);
  24.     lexp += xchar;
  25.     if (_LMAX <= lexp)
  26.         {    /* overflow, return +/-INF */
  27.         *px = ps[_L0] & _LSIGN ? -_LInf._L : _LInf._L;
  28.         return (INF);
  29.         }
  30.     else if (0 <= lexp)
  31.         {    /* finite result, repack */
  32.         ps[_L0] = ps[_L0] & _LSIGN | (short)lexp;
  33.         return (FINITE);
  34.         }
  35.     else
  36.         {    /* denormalized, scale */
  37.         unsigned short sign = ps[_L0] & _LSIGN;
  38.  
  39.         ps[_L0] = 1;
  40.         if (--lexp <= -112)
  41.             {    /* underflow, return +/-0 */
  42.             ps[_L1] = 0, ps[_L2] = 0, ps[_L3] = 0, ps[_L4] = 0;
  43.             ps[_L5] = 0, ps[_L6] = 0, ps[_L7] = 0;
  44.             return (0);
  45.             }
  46.         else
  47.             {    /* nonzero, align fraction */
  48.             short xexp;
  49.             for (xexp = lexp; xexp <= -16; xexp += 16)
  50.                 {    /* scale by words */
  51.                 ps[_L7] = ps[_L6], ps[_L6] = ps[_L5];
  52.                 ps[_L5] = ps[_L4], ps[_L4] = ps[_L3];
  53.                 ps[_L3] = ps[_L2], ps[_L2] = ps[_L1];
  54.                 ps[_L1] = ps[_L0], ps[_L0] = 0;
  55.                 }
  56.             if ((xexp = -xexp) != 0)
  57.                 {    /* scale by bits */
  58.                 ps[_L7] = ps[_L7] >> xexp
  59.                     | ps[_L6] << 16 - xexp;
  60.                 ps[_L6] = ps[_L6] >> xexp
  61.                     | ps[_L5] << 16 - xexp;
  62.                 ps[_L5] = ps[_L5] >> xexp
  63.                     | ps[_L4] << 16 - xexp;
  64.                 ps[_L4] = ps[_L4] >> xexp
  65.                     | ps[_L3] << 16 - xexp;
  66.                 ps[_L3] = ps[_L3] >> xexp
  67.                     | ps[_L2] << 16 - xexp;
  68.                 ps[_L2] = ps[_L2] >> xexp
  69.                     | ps[_L1] << 16 - xexp;
  70.                 ps[_L1] = ps[_L1] >> xexp
  71.                     | ps[_L0] << 16 - xexp;
  72.                 }
  73.             ps[_L0] = sign;
  74.             return (FINITE);
  75.             }
  76.         }
  77.     }
  78. #else    /*    _DLONG && !_LONG_DOUBLE_HAS_HIDDEN_BIT */
  79. _CRTIMP2 short _LDscale(long double *px, long lexp)
  80.     {    /* scale *px by 2^lexp with checking */
  81.     unsigned short *ps = (unsigned short *)px;
  82.     short xchar = ps[_L0] & _LMASK;
  83.  
  84.     if (xchar == _LMAX)
  85.         return ((ps[_L1] & 0x7fff) != 0 || ps[_L2] != 0
  86.             || ps[_L3] != 0 || ps[_L4] != 0 ? NAN : INF);
  87.     else if (xchar == 0 && ps[_L1] == 0 && ps[_L2] == 0
  88.         && ps[_L3] == 0 && ps[_L4] == 0)
  89.         return (0);
  90.     lexp += xchar + _LDnorm(ps);
  91.     if (_LMAX <= lexp)
  92.         {    /* overflow, return +/-INF */
  93.         *px = ps[_L0] & _LSIGN ? -_LInf._L : _LInf._L;
  94.         return (INF);
  95.         }
  96.     else if (0 <= lexp)
  97.         {    /* finite result, repack */
  98.         ps[_L0] = ps[_L0] & _LSIGN | (short)lexp;
  99.         return (FINITE);
  100.         }
  101.     else
  102.         {    /* denormalized, scale */
  103.         ps[_L0] &= _LSIGN;
  104.         if (lexp <= -64)
  105.             {    /* underflow, return +/-0 */
  106.             ps[_L1] = 0, ps[_L2] = 0;
  107.             ps[_L3] = 0, ps[_L4] = 0;
  108.             return (0);
  109.             }
  110.         else
  111.             {    /* nonzero, align fraction */
  112.             short xexp;
  113.             for (xexp = lexp; xexp <= -16; xexp += 16)
  114.                 {    /* scale by words */
  115.                 ps[_L4] = ps[_L3], ps[_L3] = ps[_L2];
  116.                 ps[_L2] = ps[_L1], ps[_L1] = 0;
  117.                 }
  118.             if ((xexp = -xexp) != 0)
  119.                 {    /* scale by bits */
  120.                 ps[_L4] = ps[_L4] >> xexp
  121.                     | ps[_L3] << 16 - xexp;
  122.                 ps[_L3] = ps[_L3] >> xexp
  123.                     | ps[_L2] << 16 - xexp;
  124.                 ps[_L2] = ps[_L2] >> xexp
  125.                     | ps[_L1] << 16 - xexp;
  126.                 ps[_L1] >>= xexp;
  127.                 }
  128.             return (FINITE);
  129.             }
  130.         }
  131.     }
  132. #endif
  133. _STD_END
  134.  
  135. /*
  136.  * Copyright (c) 1994 by P.J. Plauger.  ALL RIGHTS RESERVED. 
  137.  * Consult your license regarding permissions and restrictions.
  138.  */
  139.  
  140. /*
  141. 941029 pjp: added _STD machinery
  142.  */
  143.