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.

139 lines
3.6 KiB

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