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.

216 lines
4.7 KiB

  1. //---------------------------------------------------------------------------
  2. // Package Title ratpak
  3. // File num.c
  4. // Author Timothy David Corrie Jr. ([email protected])
  5. // Copyright (C) 1995-99 Microsoft
  6. // Date 01-16-95
  7. //
  8. //
  9. // Description
  10. //
  11. // Contains routines for and, or, xor, not and other support
  12. //
  13. //---------------------------------------------------------------------------
  14. #include <windows.h>
  15. #include <ratpak.h>
  16. void lshrat( PRAT *pa, PRAT b )
  17. {
  18. PRAT pwr=NULL;
  19. long intb;
  20. intrat(pa);
  21. if ( !zernum( (*pa)->pp ) )
  22. {
  23. // If input is zero we're done.
  24. if ( rat_gt( b, rat_max_exp ) )
  25. {
  26. // Don't attempt lsh of anything big
  27. throw( CALC_E_DOMAIN );
  28. }
  29. intb = rattolong(b);
  30. DUPRAT(pwr,rat_two);
  31. ratpowlong(&pwr,intb);
  32. mulrat(pa,pwr);
  33. destroyrat(pwr);
  34. }
  35. }
  36. void rshrat( PRAT *pa, PRAT b )
  37. {
  38. PRAT pwr=NULL;
  39. long intb;
  40. intrat(pa);
  41. if ( !zernum( (*pa)->pp ) )
  42. {
  43. // If input is zero we're done.
  44. if ( rat_lt( b, rat_min_exp ) )
  45. {
  46. // Don't attempt rsh of anything big and negative.
  47. throw( CALC_E_DOMAIN );
  48. }
  49. intb = rattolong(b);
  50. DUPRAT(pwr,rat_two);
  51. ratpowlong(&pwr,intb);
  52. divrat(pa,pwr);
  53. destroyrat(pwr);
  54. }
  55. }
  56. void boolrat( PRAT *pa, PRAT b, int func );
  57. void boolnum( PNUMBER *pa, PNUMBER b, int func );
  58. enum {
  59. FUNC_AND,
  60. FUNC_OR,
  61. FUNC_XOR
  62. } BOOL_FUNCS;
  63. void andrat( PRAT *pa, PRAT b )
  64. {
  65. boolrat( pa, b, FUNC_AND );
  66. }
  67. void orrat( PRAT *pa, PRAT b )
  68. {
  69. boolrat( pa, b, FUNC_OR );
  70. }
  71. void xorrat( PRAT *pa, PRAT b )
  72. {
  73. boolrat( pa, b, FUNC_XOR );
  74. }
  75. //---------------------------------------------------------------------------
  76. //
  77. // FUNCTION: boolrat
  78. //
  79. // ARGUMENTS: pointer to a rational a second rational.
  80. //
  81. // RETURN: None, changes pointer.
  82. //
  83. // DESCRIPTION: Does the rational equivalent of *pa op= b;
  84. //
  85. //---------------------------------------------------------------------------
  86. void boolrat( PRAT *pa, PRAT b, int func )
  87. {
  88. PRAT tmp=NULL;
  89. intrat( pa );
  90. DUPRAT(tmp,b);
  91. intrat( &tmp );
  92. boolnum( &((*pa)->pp), tmp->pp, func );
  93. destroyrat(tmp);
  94. }
  95. //---------------------------------------------------------------------------
  96. //
  97. // FUNCTION: boolnum
  98. //
  99. // ARGUMENTS: pointer to a number a second number
  100. //
  101. // RETURN: None, changes first pointer.
  102. //
  103. // DESCRIPTION: Does the number equivalent of *pa &= b.
  104. // nRadix doesn't matter for logicals.
  105. // WARNING: Assumes numbers are unsigned.
  106. //
  107. //---------------------------------------------------------------------------
  108. void boolnum( PNUMBER *pa, PNUMBER b, int func )
  109. {
  110. PNUMBER c=NULL;
  111. PNUMBER a=NULL;
  112. MANTTYPE *pcha;
  113. MANTTYPE *pchb;
  114. MANTTYPE *pchc;
  115. long cdigits;
  116. long mexp;
  117. MANTTYPE da;
  118. MANTTYPE db;
  119. a=*pa;
  120. cdigits = max( a->cdigit+a->exp, b->cdigit+b->exp ) -
  121. min( a->exp, b->exp );
  122. createnum( c, cdigits );
  123. c->exp = min( a->exp, b->exp );
  124. mexp = c->exp;
  125. c->cdigit = cdigits;
  126. pcha = MANT(a);
  127. pchb = MANT(b);
  128. pchc = MANT(c);
  129. for ( ;cdigits > 0; cdigits--, mexp++ )
  130. {
  131. da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp >
  132. (c->cdigit - a->cdigit) ) ) ?
  133. *pcha++ : 0 );
  134. db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp >
  135. (c->cdigit - b->cdigit) ) ) ?
  136. *pchb++ : 0 );
  137. switch ( func )
  138. {
  139. case FUNC_AND:
  140. *pchc++ = da & db;
  141. break;
  142. case FUNC_OR:
  143. *pchc++ = da | db;
  144. break;
  145. case FUNC_XOR:
  146. *pchc++ = da ^ db;
  147. break;
  148. }
  149. }
  150. c->sign = a->sign;
  151. while ( c->cdigit > 1 && *(--pchc) == 0 )
  152. {
  153. c->cdigit--;
  154. }
  155. destroynum( *pa );
  156. *pa=c;
  157. }
  158. //-----------------------------------------------------------------------------
  159. //
  160. // FUNCTION: modrat
  161. //
  162. // ARGUMENTS: pointer to a rational a second rational.
  163. //
  164. // RETURN: None, changes pointer.
  165. //
  166. // DESCRIPTION: Does the rational equivalent of frac(*pa);
  167. //
  168. //-----------------------------------------------------------------------------
  169. void modrat( PRAT *pa, PRAT b )
  170. {
  171. PRAT tmp = NULL;
  172. if ( zerrat( b ) )
  173. {
  174. throw CALC_E_INDEFINITE;
  175. }
  176. DUPRAT(tmp,b);
  177. mulnumx( &((*pa)->pp), tmp->pq );
  178. mulnumx( &(tmp->pp), (*pa)->pq );
  179. remnum( &((*pa)->pp), tmp->pp, BASEX );
  180. mulnumx( &((*pa)->pq), tmp->pq );
  181. //Get *pa back in the integer over integer form.
  182. RENORMALIZE(*pa);
  183. destroyrat( tmp );
  184. }