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

  1. /* _LDnorm function -- IEEE 754 version */
  2. #include "wctype.h"
  3. #include "xmath.h"
  4. _STD_BEGIN
  5.  
  6. #if !_DLONG
  7.     /* not needed */
  8. #elif _LONG_DOUBLE_HAS_HIDDEN_BIT
  9. _CRTIMP2 short _LDnorm(unsigned short *ps)
  10.     {    /* normalize long double fraction -- SPARC */
  11.     short xchar;
  12.     unsigned short sign = ps[_L0];
  13.  
  14.     xchar = 1;
  15.     if (ps[_L1] != 0 || ps[_L2] != 0 || ps[_L3] != 0
  16.         || ps[_L4] != 0 || ps[_L5] != 0 || ps[_L6] != 0
  17.         || ps[_L7] != 0)
  18.         {    /* nonzero, scale */
  19.         for (ps[_L0] = 0; ps[_L0] == 0 && ps[_L1] < 0x100;
  20.             xchar -= 16)
  21.             {    /* shift left by 16 */
  22.             ps[_L0] = ps[_L1];
  23.             ps[_L1] = ps[_L2], ps[_L2] = ps[_L3];
  24.             ps[_L3] = ps[_L4], ps[_L4] = ps[_L5];
  25.             ps[_L5] = ps[_L6], ps[_L6] = ps[_L7];
  26.             ps[_L7] = 0;
  27.             }
  28.         for (; ps[_L0] == 0; --xchar)
  29.             {    /* shift left by 1 */
  30.             ps[_L0] = ps[_L0] << 1 | ps[_L1] >> 15;
  31.             ps[_L1] = ps[_L1] << 1 | ps[_L2] >> 15;
  32.             ps[_L2] = ps[_L2] << 1 | ps[_L3] >> 15;
  33.             ps[_L3] = ps[_L3] << 1 | ps[_L4] >> 15;
  34.             ps[_L4] = ps[_L4] << 1 | ps[_L5] >> 15;
  35.             ps[_L5] = ps[_L5] << 1 | ps[_L6] >> 15;
  36.             ps[_L6] = ps[_L6] << 1 | ps[_L7] >> 15;
  37.             ps[_L7] <<= 1;
  38.             }
  39.         for (; 1 < ps[_L0]; ++xchar)
  40.             {    /* shift right by 1 */
  41.             ps[_L7] = ps[_L7] >> 1 | ps[_L6] << 15;
  42.             ps[_L6] = ps[_L6] >> 1 | ps[_L5] << 15;
  43.             ps[_L5] = ps[_L5] >> 1 | ps[_L4] << 15;
  44.             ps[_L4] = ps[_L4] >> 1 | ps[_L3] << 15;
  45.             ps[_L3] = ps[_L3] >> 1 | ps[_L2] << 15;
  46.             ps[_L2] = ps[_L2] >> 1 | ps[_L1] << 15;
  47.             ps[_L1] = ps[_L1] >> 1 | ps[_L0] << 15;
  48.             ps[_L0] >>= 1;
  49.             }
  50.         }
  51.     ps[_L0] = sign;
  52.     return (xchar);
  53.     }
  54. #else    /* !_LONG_DOUBLE_HAS_HIDDEN_BIT */
  55. _CRTIMP2 short _LDnorm(unsigned short *ps)
  56.     {    /* normalize long double fraction */
  57.     short xchar;
  58.     unsigned short sign = ps[_L0];
  59.  
  60.     xchar = 0;
  61.     for (ps[_L0] = 0; ps[_L0] == 0 && ps[_L1] < 0x100;
  62.         xchar -= 16)
  63.         {    /* shift left by 16 */
  64.         ps[_L0] = ps[_L1];
  65.         ps[_L1] = ps[_L2], ps[_L2] = ps[_L3];
  66.         ps[_L3] = ps[_L4], ps[_L4] = 0;
  67.         }
  68.     if (ps[_L0] == 0)
  69.         for (; ps[_L1] < (1U << _LOFF); --xchar)
  70.             {    /* shift left by 1 */
  71.             ps[_L1] = ps[_L1] << 1 | ps[_L2] >> 15;
  72.             ps[_L2] = ps[_L2] << 1 | ps[_L3] >> 15;
  73.             ps[_L3] = ps[_L3] << 1 | ps[_L4] >> 15;
  74.             ps[_L4] <<= 1;
  75.             }
  76.     for (; ps[_L0] != 0; ++xchar)
  77.         {    /* shift right by 1 */
  78.         ps[_L4] = ps[_L4] >> 1 | ps[_L3] << 15;
  79.         ps[_L3] = ps[_L3] >> 1 | ps[_L2] << 15;
  80.         ps[_L2] = ps[_L2] >> 1 | ps[_L1] << 15;
  81.         ps[_L1] = ps[_L1] >> 1 | ps[_L0] << 15;
  82.         ps[_L0] >>= 1;
  83.         }
  84.     ps[_L0] = sign;
  85.     return (xchar);
  86.     }
  87. #endif
  88. _STD_END
  89.  
  90. /*
  91.  * Copyright (c) 1994 by P.J. Plauger.  ALL RIGHTS RESERVED. 
  92.  * Consult your license regarding permissions and restrictions.
  93.  */
  94.  
  95. /*
  96. 941029 pjp: added _STD machinery
  97.  */
  98.