Leaked source code of windows server 2003
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.

229 lines
6.6 KiB

  1. #include <windows.h>
  2. #include <stdlib.h>
  3. #include "scicalc.h"
  4. #include "unifunc.h"
  5. #include "..\ratpak\debug.h"
  6. /**************************************************************************\
  7. * *
  8. * *
  9. * *
  10. * # # ##### *
  11. * # # # # # *
  12. * # # # # # # # *
  13. * # ### ### # # *
  14. * # # ### # # # ### # # ### ##### # ### ### ### *
  15. * # ## # # # ## # # # # # # ## # # # *
  16. * # # # # # # # # # ##### # # ##### # *
  17. * # # # # # # # # # # # # # # ## *
  18. * # # # # # # # # # ### # # ### ### ## *
  19. * *
  20. * *
  21. * Infinte Precision Production Version *
  22. * *
  23. \**************************************************************************/
  24. //
  25. // RETAIL version of NUMOBJ math that uses Infinite Precision
  26. //
  27. // History
  28. //
  29. // 16-Nov-1996 JonPa Wrote it
  30. // whenever-97 ToddB Rewrote it using improved ratpak model
  31. //
  32. /*****************************************************************\
  33. *
  34. * Generic Math Package support routines and variables
  35. *
  36. * History:
  37. * 01-Dec-1996 JonPa Wrote them
  38. * whenever-97 ToddB Rewrote them
  39. *
  40. \*****************************************************************/
  41. //
  42. // Worker for NumObjRecalcConstants
  43. //
  44. // Returns the nearest power of two
  45. //
  46. int QuickLog2( int iNum )
  47. {
  48. int iRes = 0;
  49. // while first digit is a zero
  50. while ( !(iNum & 1) )
  51. {
  52. iRes++;
  53. iNum >>= 1;
  54. }
  55. // if our number isn't a perfect square
  56. if ( iNum = iNum >> 1 )
  57. {
  58. // find the largest digit
  59. while ( iNum = iNum >> 1 )
  60. ++iRes;
  61. // and then add two
  62. iRes += 2;
  63. }
  64. return iRes;
  65. }
  66. ////////////////////////////////////////////////////////////////////////
  67. //
  68. // UpdateMaxIntDigits
  69. //
  70. // determine the maximum number of digits needed for the current precision,
  71. // word size, and base. This number is conservative towards the small side
  72. // such that there may be some extra bits left over. The number of extra
  73. // bits is returned. For example, base 8 requires 3 bits per digit. A word
  74. // size of 32 bits allows for 10 digits with a remainder of two bits. Bases
  75. // that require variable numnber of bits (non-power-of-two bases) are approximated
  76. // by the next highest power-of-two base (again, to be conservative and gaurentee
  77. // there will be no over flow verse the current word size for numbers entered).
  78. // Base 10 is a special case and always uses the base 10 precision (nPrecision).
  79. void UpdateMaxIntDigits()
  80. {
  81. extern int gcIntDigits;
  82. int iRemainderBits;
  83. if ( nRadix == 10 )
  84. {
  85. gcIntDigits = nPrecision;
  86. iRemainderBits = 0;
  87. }
  88. else
  89. {
  90. int log2;
  91. log2 = QuickLog2( nRadix );
  92. ASSERT( 0 != log2 ); // same as ASSERT( nRadix != 1 )
  93. gcIntDigits = dwWordBitWidth / log2;
  94. iRemainderBits = dwWordBitWidth % log2;
  95. }
  96. }
  97. void BaseOrPrecisionChanged( void )
  98. {
  99. extern LONG dwWordBitWidth;
  100. extern int gcIntDigits;
  101. UpdateMaxIntDigits();
  102. if ( 10 == nRadix )
  103. {
  104. // to prevent unwanted rounded digits from showing up in the
  105. // gcIntDigits + 1 spot during non-integer mode we don't want
  106. // to add the extra 1 that we ortherwise add
  107. ChangeConstants( nRadix, gcIntDigits );
  108. }
  109. else
  110. {
  111. ChangeConstants( nRadix, gcIntDigits+1 );
  112. }
  113. }
  114. /*****************************************************************\
  115. *
  116. * Unary functions
  117. *
  118. * History:
  119. * 01-Dec-1996 JonPa Wrote them
  120. * whenever-97 ToddB Rewrote them
  121. *
  122. \*****************************************************************/
  123. void NumObjInvert( PHNUMOBJ phno ) {
  124. DECLARE_HNUMOBJ( hno );
  125. NumObjAssign( &hno, HNO_ONE );
  126. divrat( &hno, *phno );
  127. NumObjAssign( phno, hno );
  128. NumObjDestroy( &hno );
  129. }
  130. void NumObjAntiLog10( PHNUMOBJ phno ) {
  131. DECLARE_HNUMOBJ( hno );
  132. NumObjSetIntValue( &hno, 10 );
  133. powrat( &hno, *phno );
  134. NumObjAssign( phno, hno );
  135. NumObjDestroy( &hno );
  136. }
  137. void NumObjNot( PHNUMOBJ phno )
  138. {
  139. if ( nRadix == 10 )
  140. {
  141. intrat( phno );
  142. addrat( phno, HNO_ONE );
  143. NumObjNegate( phno );
  144. }
  145. else
  146. {
  147. ASSERT( (nHexMode >= 0) && (nHexMode <= 3) );
  148. ASSERT( phno );
  149. ASSERT( *phno );
  150. ASSERT( g_ahnoChopNumbers[ nHexMode ] );
  151. xorrat( phno, g_ahnoChopNumbers[ nHexMode ] );
  152. }
  153. }
  154. void NumObjSin( PHNUMOBJ phno )
  155. {
  156. ASSERT(( nDecMode == ANGLE_DEG ) || ( nDecMode == ANGLE_RAD ) || ( nDecMode == ANGLE_GRAD ));
  157. sinanglerat( (PRAT *)phno, nDecMode );
  158. NumObjCvtEpsilonToZero( phno );
  159. }
  160. void NumObjCos( PHNUMOBJ phno )
  161. {
  162. ASSERT(( nDecMode == ANGLE_DEG ) || ( nDecMode == ANGLE_RAD ) || ( nDecMode == ANGLE_GRAD ));
  163. cosanglerat( (PRAT *)phno, nDecMode );
  164. NumObjCvtEpsilonToZero( phno );
  165. }
  166. void NumObjTan( PHNUMOBJ phno )
  167. {
  168. ASSERT(( nDecMode == ANGLE_DEG ) || ( nDecMode == ANGLE_RAD ) || ( nDecMode == ANGLE_GRAD ));
  169. tananglerat( (PRAT *)phno, nDecMode );
  170. NumObjCvtEpsilonToZero( phno );
  171. }
  172. /******************************************************************\
  173. *
  174. * Number format conversion routines
  175. *
  176. * History:
  177. * 06-Dec-1996 JonPa wrote them
  178. \******************************************************************/
  179. void NumObjSetIntValue( PHNUMOBJ phnol, LONG i ) {
  180. PRAT pr = NULL;
  181. pr = longtorat( i );
  182. NumObjAssign( phnol, (HNUMOBJ)pr );
  183. destroyrat(pr);
  184. }
  185. void NumObjGetSzValue( LPTSTR *ppszNum, int* pcchNum, HNUMOBJ hnoNum, INT nRadix, NUMOBJ_FMT fmt )
  186. {
  187. LPTSTR psz;
  188. int cchNum;
  189. psz = putrat( &cchNum, &hnoNum, nRadix, fmt );
  190. if (psz != NULL) {
  191. if (*ppszNum != NULL) {
  192. NumObjFreeMem( *ppszNum );
  193. }
  194. *ppszNum = psz;
  195. *pcchNum = cchNum;
  196. }
  197. }