Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
3.6 KiB

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