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.

130 lines
2.6 KiB

  1. /***
  2. *util.c - utilities for fp transcendentals
  3. *
  4. * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * _set_exp and _add_exp are as those defined in Cody & Waite
  8. *
  9. *Revision History:
  10. * 08-15-91 GDP written
  11. * 10-20-91 GDP removed _rint, unsafe_intrnd
  12. * 02-05-92 GDP added _fpclass
  13. * 03-27-92 GDP added _d_min
  14. * 06-23-92 GDP added _d_mzero
  15. *
  16. *******************************************************************************/
  17. #include "trans.h"
  18. /* define special values */
  19. _dbl _d_inf = {SET_DBL (0x7ff00000, 0x0) }; //positive infinity
  20. _dbl _d_ind = {SET_DBL (D_IND_HI, D_IND_LO)}; //real indefinite
  21. _dbl _d_max = {SET_DBL (0x7fefffff, 0xffffffff)}; //max double
  22. _dbl _d_min = {SET_DBL (0x00100000, 0x00000000)}; //min normalized double
  23. _dbl _d_mzero = {SET_DBL (0x80000000, 0x00000000)}; //negative zero
  24. double _set_exp(double x, int exp)
  25. /* does not check validity of exp */
  26. {
  27. double retval;
  28. int biased_exp;
  29. retval = x;
  30. biased_exp = exp + D_BIASM1;
  31. *D_EXP(retval) = (unsigned short) (*D_EXP(x) & 0x800f | (biased_exp << 4));
  32. return retval;
  33. }
  34. int _get_exp(double x)
  35. {
  36. signed short exp;
  37. exp = (signed short)((*D_EXP(x) & 0x7ff0) >> 4);
  38. exp -= D_BIASM1; //unbias
  39. return (int) exp;
  40. }
  41. double _add_exp(double x, int exp)
  42. {
  43. return _set_exp(x, INTEXP(x)+exp);
  44. }
  45. double _set_bexp(double x, int bexp)
  46. /* does not check validity of bexp */
  47. {
  48. double retval;
  49. retval = x;
  50. *D_EXP(retval) = (unsigned short) (*D_EXP(x) & 0x800f | (bexp << 4));
  51. return retval;
  52. }
  53. int _sptype(double x)
  54. {
  55. if (IS_D_INF(x))
  56. return T_PINF;
  57. if (IS_D_MINF(x))
  58. return T_NINF;
  59. if (IS_D_QNAN(x))
  60. return T_QNAN;
  61. if (IS_D_SNAN(x))
  62. return T_SNAN;
  63. return 0;
  64. }
  65. /***
  66. *double _decomp(double x, double *expptr)
  67. *
  68. *Purpose:
  69. * decompose a number to a normalized mantisa and exponent
  70. *
  71. *Entry:
  72. *
  73. *Exit:
  74. *
  75. *Exceptions:
  76. *
  77. *******************************************************************************/
  78. double _decomp(double x, int *pexp)
  79. {
  80. int exp;
  81. double man;
  82. if (x == 0) {
  83. man = 0;
  84. exp = 0;
  85. }
  86. else if (IS_D_DENORM(x)) {
  87. int neg;
  88. exp = 1-D_BIASM1;
  89. neg = x < 0.0;
  90. while((*D_EXP(x) & 0x0010) == 0) {
  91. /* shift mantissa to the left until bit 52 is 1 */
  92. (*D_HI(x)) <<= 1;
  93. if (*D_LO(x) & 0x80000000)
  94. (*D_HI(x)) |= 0x1;
  95. (*D_LO(x)) <<= 1;
  96. exp--;
  97. }
  98. (*D_EXP(x)) &= 0xffef; /* clear bit 52 */
  99. if (neg) {
  100. (*D_EXP(x)) |= 0x8000; /* set sign bit */
  101. }
  102. man = _set_exp(x,0);
  103. }
  104. else {
  105. man = _set_exp(x,0);
  106. exp = INTEXP(x);
  107. }
  108. *pexp = exp;
  109. return man;
  110. }