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.

535 lines
20 KiB

  1. #pragma warning( disable : 4200 )
  2. //-----------------------------------------------------------------------------
  3. // Package Title ratpak
  4. // File ratpak.h
  5. // Author Timothy David Corrie Jr. ([email protected])
  6. // Copyright (C) 1995-99 Microsoft
  7. // Date 01-16-95
  8. //
  9. //
  10. // Description
  11. //
  12. // Infinite precision math package header file, if you use ratpak.lib you
  13. // need to include this header.
  14. //
  15. //-----------------------------------------------------------------------------
  16. #include "CalcErr.h"
  17. #define BASEXPWR 31L // Internal log2(BASEX)
  18. #define BASEX 0x80000000 // Internal nRadix used in calculations, hope to raise
  19. // this to 2^32 after solving scaling problems with
  20. // overflow detection esp. in mul
  21. typedef unsigned long MANTTYPE;
  22. typedef unsigned __int64 TWO_MANTTYPE;
  23. enum eNUMOBJ_FMT {
  24. FMT_FLOAT, // returns floating point, or exponential if number is too big
  25. FMT_SCIENTIFIC, // always returns scientific notation
  26. FMT_ENGINEERING // always returns engineering notation such that exponent is a multiple of 3
  27. };
  28. enum eANGLE_TYPE {
  29. ANGLE_DEG, // Calculate trig using 360 degrees per revolution
  30. ANGLE_RAD, // Calculate trig using 2 pi radians per revolution
  31. ANGLE_GRAD // Calculate trig using 400 gradients per revolution
  32. };
  33. typedef enum eNUMOBJ_FMT NUMOBJ_FMT;
  34. typedef enum eANGLE_TYPE ANGLE_TYPE;
  35. typedef int BOOL;
  36. //-----------------------------------------------------------------------------
  37. //
  38. // NUMBER type is a representation of a generic sized generic nRadix number
  39. //
  40. //-----------------------------------------------------------------------------
  41. typedef struct _number
  42. {
  43. long sign; // The sign of the mantissa, +1, or -1
  44. long cdigit; // The number of digits, or what passes for digits in the
  45. // nRadix being used.
  46. long exp; // The offset of digits from the nRadix point
  47. // (decimal point in nRadix 10)
  48. MANTTYPE mant[0];
  49. // This is actually allocated as a continuation of the
  50. // NUMBER structure.
  51. } NUMBER, *PNUMBER, **PPNUMBER;
  52. //-----------------------------------------------------------------------------
  53. //
  54. // RAT type is a representation nRadix on 2 NUMBER types.
  55. // pp/pq, where pp and pq are pointers to integral NUMBER types.
  56. //
  57. //-----------------------------------------------------------------------------
  58. typedef struct _rat
  59. {
  60. PNUMBER pp;
  61. PNUMBER pq;
  62. } RAT, *PRAT;
  63. //-----------------------------------------------------------------------------
  64. //
  65. // LINKEDLIST is an aid for division, it contains foreward and reverse links
  66. // to a list of NUMBERS.
  67. //
  68. //-----------------------------------------------------------------------------
  69. typedef struct _linkedlist
  70. {
  71. PNUMBER pnum;
  72. struct _linkedlist *llnext;
  73. struct _linkedlist *llprev;
  74. } LINKEDLIST, *PLINKEDLIST;
  75. #if !defined( TRUE )
  76. #define TRUE 1
  77. #endif
  78. #if !defined( FALSE )
  79. #define FALSE 0
  80. #endif
  81. #define MAX_LONG_SIZE 33 // Base 2 requires 32 'digits'
  82. //-----------------------------------------------------------------------------
  83. //
  84. // List of useful constants for evaluation, note this list needs to be
  85. // initialized.
  86. //
  87. //-----------------------------------------------------------------------------
  88. extern PNUMBER num_one;
  89. extern PNUMBER num_two;
  90. extern PNUMBER num_five;
  91. extern PNUMBER num_six;
  92. extern PNUMBER num_nRadix;
  93. extern PNUMBER num_ten;
  94. extern PRAT ln_ten;
  95. extern PRAT ln_two;
  96. extern PRAT rat_zero;
  97. extern PRAT rat_neg_one;
  98. extern PRAT rat_one;
  99. extern PRAT rat_two;
  100. extern PRAT rat_six;
  101. extern PRAT rat_half;
  102. extern PRAT rat_ten;
  103. extern PRAT pt_eight_five;
  104. extern PRAT pi;
  105. extern PRAT pi_over_two;
  106. extern PRAT two_pi;
  107. extern PRAT one_pt_five_pi;
  108. extern PRAT e_to_one_half;
  109. extern PRAT rat_exp;
  110. extern PRAT rad_to_deg;
  111. extern PRAT rad_to_grad;
  112. extern PRAT rat_qword;
  113. extern PRAT rat_dword;
  114. extern PRAT rat_word;
  115. extern PRAT rat_byte;
  116. extern PRAT rat_360;
  117. extern PRAT rat_400;
  118. extern PRAT rat_180;
  119. extern PRAT rat_200;
  120. extern PRAT rat_nRadix;
  121. extern PRAT rat_smallest;
  122. extern PRAT rat_negsmallest;
  123. extern PRAT rat_max_exp;
  124. extern PRAT rat_min_exp;
  125. extern PRAT rat_min_long;
  126. // MANT returns a long pointer to the mantissa of number 'a'
  127. #define MANT(a) ((a)->mant)
  128. // DUPNUM Duplicates a number taking care of allocation and internals
  129. #define DUPNUM(a,b) destroynum(a);createnum( a, b->cdigit ); \
  130. memcpy( a, b, (int)( sizeof( NUMBER ) + ( b->cdigit )*(sizeof(MANTTYPE)) ) );
  131. // DUPRAT Duplicates a rational taking care of allocation and internals
  132. #define DUPRAT(a,b) destroyrat(a);createrat(a);DUPNUM((a)->pp,(b)->pp);DUPNUM((a)->pq,(b)->pq);
  133. // LOG*RADIX calculates the integral portion of the log of a number in
  134. // the base currently being used, only accurate to within ratio
  135. #define LOGNUMRADIX(pnum) (((pnum)->cdigit+(pnum)->exp)*ratio)
  136. #define LOGRATRADIX(prat) (LOGNUMRADIX((prat)->pp)-LOGNUMRADIX((prat)->pq))
  137. // LOG*2 calculates the integral portion of the log of a number in
  138. // the internal base being used, only accurate to within ratio
  139. #define LOGNUM2(pnum) ((pnum)->cdigit+(pnum)->exp)
  140. #define LOGRAT2(prat) (LOGNUM2((prat)->pp)-LOGNUM2((prat)->pq))
  141. #if defined( DEBUG )
  142. //-----------------------------------------------------------------------------
  143. //
  144. // Debug versions of rational number creation and destruction routines.
  145. // used for debugging allocation errors.
  146. //
  147. //-----------------------------------------------------------------------------
  148. #define createrat(y) y=_createrat();fprintf( stderr, "createrat %lx %s file= %s, line= %d\n", y, # y, __FILE__, __LINE__ )
  149. #define destroyrat(x) fprintf( stderr, "destroyrat %lx file= %s, line= %d\n", x, __FILE__, __LINE__ ),_destroyrat(x),x=NULL
  150. #define createnum(y,x) y=_createnum(x);fprintf( stderr, "createnum %lx %s file= %s, line= %d\n", y, # y, __FILE__, __LINE__ );
  151. #define destroynum(x) fprintf( stderr, "destroynum %lx file= %s, line= %d\n", x, __FILE__, __LINE__ ),_destroynum(x),x=NULL
  152. #else
  153. #define createrat(y) y=_createrat()
  154. #define destroyrat(x) _destroyrat(x),x=NULL
  155. #define createnum(y,x) y=_createnum(x)
  156. #define destroynum(x) _destroynum(x),x=NULL
  157. #endif
  158. //-----------------------------------------------------------------------------
  159. //
  160. // Defines for checking when to stop taylor series expansions due to
  161. // precision satisfaction.
  162. //
  163. //-----------------------------------------------------------------------------
  164. // RENORMALIZE, gets the exponents non-negative.
  165. #define RENORMALIZE(x) if ( (x)->pp->exp < 0 ) { \
  166. (x)->pq->exp -= (x)->pp->exp; \
  167. (x)->pp->exp = 0; \
  168. } \
  169. if ( (x)->pq->exp < 0 ) { \
  170. (x)->pp->exp -= (x)->pq->exp; \
  171. (x)->pq->exp = 0; \
  172. }
  173. // TRIMNUM ASSUMES the number is in nRadix form NOT INTERNAL BASEX!!!
  174. #define TRIMNUM(x) if ( !ftrueinfinite ) { \
  175. long trim = (x)->cdigit - maxout-ratio;\
  176. if ( trim > 1 ) \
  177. { \
  178. memmove( MANT(x), &(MANT(x)[trim]), sizeof(MANTTYPE)*((x)->cdigit-trim) ); \
  179. (x)->cdigit -= trim; \
  180. (x)->exp += trim; \
  181. } \
  182. }
  183. // TRIMTOP ASSUMES the number is in INTERNAL BASEX!!!
  184. #define TRIMTOP(x) if ( !ftrueinfinite ) { \
  185. long trim = (x)->pp->cdigit - (maxout/ratio) - 2;\
  186. if ( trim > 1 ) \
  187. { \
  188. memmove( MANT((x)->pp), &(MANT((x)->pp)[trim]), sizeof(MANTTYPE)*((x)->pp->cdigit-trim) ); \
  189. (x)->pp->cdigit -= trim; \
  190. (x)->pp->exp += trim; \
  191. } \
  192. trim = min((x)->pp->exp,(x)->pq->exp);\
  193. (x)->pp->exp -= trim;\
  194. (x)->pq->exp -= trim;\
  195. }
  196. #define CLOSE_ENOUGH_RAT(a,b) ( ( ( ( ( a->pp->cdigit + a->pp->exp ) - \
  197. ( a->pq->cdigit + a->pq->exp ) ) - ( ( b->pp->cdigit + b->pp->exp ) - \
  198. ( b->pq->cdigit + b->pq->exp ) ) ) * ratio > maxout ) || fhalt )
  199. #define SMALL_ENOUGH_RAT(a) (zernum(a->pp) || ( ( ( a->pq->cdigit + a->pq->exp ) - ( a->pp->cdigit + a->pp->exp ) - 1 ) * ratio > maxout ) || fhalt )
  200. //-----------------------------------------------------------------------------
  201. //
  202. // Defines for setting up taylor series expansions for infinite precision
  203. // functions.
  204. //
  205. //-----------------------------------------------------------------------------
  206. #define CREATETAYLOR() PRAT xx=NULL;\
  207. PNUMBER n2=NULL; \
  208. PRAT pret=NULL; \
  209. PRAT thisterm=NULL; \
  210. DUPRAT(xx,*px); \
  211. mulrat(&xx,*px); \
  212. createrat(pret); \
  213. pret->pp=longtonum( 0L, BASEX ); \
  214. pret->pq=longtonum( 0L, BASEX );
  215. #define DESTROYTAYLOR() destroynum( n2 ); \
  216. destroyrat( xx );\
  217. destroyrat( thisterm );\
  218. destroyrat( *px );\
  219. trimit(&pret);\
  220. *px=pret;
  221. // SUM(a,b) is the rational equivalent of a += b
  222. #define SUM(a,b) addnum( &a, b, BASEX);
  223. // INC(a) is the rational equivalent of a++
  224. // Check to see if we can avoid doing this the hard way.
  225. #define INC(a) if ( a->mant[0] < BASEX - 1 ) \
  226. { \
  227. a->mant[0]++; \
  228. } \
  229. else \
  230. { \
  231. addnum( &a, num_one, BASEX); \
  232. }
  233. #define MSD(x) ((x)->mant[(x)->cdigit-1])
  234. // MULNUM(b) is the rational equivalent of thisterm *= b where thisterm is
  235. // a rational and b is a number, NOTE this is a mixed type operation for
  236. // efficiency reasons.
  237. #define MULNUM(b) mulnumx( &(thisterm->pp), b);
  238. // DIVNUM(b) is the rational equivalent of thisterm /= b where thisterm is
  239. // a rational and b is a number, NOTE this is a mixed type operation for
  240. // efficiency reasons.
  241. #define DIVNUM(b) mulnumx( &(thisterm->pq), b);
  242. // NEXTTERM(p,d) is the rational equivalent of
  243. // thisterm *= p
  244. // d <d is usually an expansion of operations to get thisterm updated.>
  245. // pret += thisterm
  246. #define NEXTTERM(p,d) mulrat(&thisterm,p);d addrat( &pret, thisterm )
  247. // ONEOVER(x) is the rational equivalent of x=1/x
  248. #define ONEOVER(x) {PNUMBER __tmpnum;__tmpnum=x->pp;x->pp=x->pq;x->pq=__tmpnum;}
  249. #ifndef DOS
  250. # if defined(ALTERNATE_ALLOCATION)
  251. //-----------------------------------------------------------------------------
  252. //
  253. // WARNING if you change the allocation package you need to rebuild
  254. // ratpak.lib
  255. //
  256. //-----------------------------------------------------------------------------
  257. extern void *zmalloc( IN unsigned long sze );
  258. extern void zfree( IN double *pd );
  259. # else
  260. # ifdef USE_HEAPALLOC
  261. //
  262. // NT Heap macros. Calling process must create a heap with HeapCreate()
  263. //
  264. # define zmalloc(a) HeapAlloc( hheap, 0, a )
  265. # define zfree(a) HeapFree( hheap, 0, a )
  266. # elif DBG
  267. //
  268. // Debug heap workers
  269. //
  270. HLOCAL MemAllocWorker(LPSTR szFile, int iLine, UINT uFlags, UINT cBytes);
  271. HLOCAL MemFreeWorker(LPSTR szFile, int iLine, HLOCAL hMem);
  272. # define zmalloc(a) MemAllocWorker( __FILE__, __LINE__, LPTR, a )
  273. # define zfree(a) MemFreeWorker( __FILE__, __LINE__, a )
  274. # else
  275. //
  276. // Windows heap macros
  277. //
  278. # define zmalloc(a) LocalAlloc( LPTR, a )
  279. # define zfree(a) LocalFree( a )
  280. # endif
  281. # endif
  282. #endif
  283. //-----------------------------------------------------------------------------
  284. //
  285. // External variables used in the math package.
  286. //
  287. //-----------------------------------------------------------------------------
  288. extern BOOL fhalt; // contains the command to halt execution if true.
  289. extern BOOL fparserror; // set to true if last innum ended in error, else false.
  290. extern NUMOBJ_FMT fmt; // contains the format to use
  291. extern TCHAR szDec[5]; // extern decimal point representation
  292. extern long nRadix; // extern nRadix used for input and output routines
  293. extern unsigned char ftrueinfinite; // set to true to allow infinite precision
  294. // don't use unless you know what you are doing
  295. // used to help decide when to stop calculating.
  296. extern long maxout; // Maximum digits nRadix <nRadix> to use for precision.
  297. // used to help decide when to stop calculating.
  298. extern long ratio; // Internally calculated ratio of internal nRadix
  299. // v.s. nRadix used for input output number routines
  300. extern LPTSTR oom; // Out of memory error message
  301. typedef void ERRFUNC( LPTSTR szErr );
  302. typedef ERRFUNC *LPERRFUNC;
  303. extern LPERRFUNC glpErrFunc; // This function will get called if an error
  304. // occurs inside of ratpak.
  305. #ifndef DOS
  306. extern HANDLE hheap; // hheap is a pointer used in allocation, ratpak.lib
  307. // users responsibility to make sure this is set up
  308. // for use with Heap{Alloc,Free} routines.
  309. #endif
  310. //-----------------------------------------------------------------------------
  311. //
  312. // External functions defined in the math package.
  313. //
  314. //-----------------------------------------------------------------------------
  315. // Call whenever radix changes and at start of program. (Obsolete)
  316. extern void changeRadix( IN long nRadix );
  317. // Call whenever precision changes and at start of program. (Obsolete)
  318. extern void changePrecision( IN long nPrecision );
  319. // Call whenever either nRadix or nPrecision changes, is smarter about
  320. // recalculating constants.
  321. // (Prefered replacement for the ChangeRadix and ChangePrecision calls.)
  322. extern void ChangeConstants( IN long nRadix, IN long nPrecision );
  323. extern BOOL equnum( IN PNUMBER a, IN PNUMBER b ); // returns true of a == b
  324. extern BOOL lessnum( IN PNUMBER a, IN PNUMBER b ); // returns true of a < b
  325. extern BOOL zernum( IN PNUMBER a ); // returns true of a == 0
  326. extern BOOL zerrat( IN PRAT a ); // returns true if a == 0/q
  327. extern TCHAR *putnum(OUT int* pcchNum, IN OUT PNUMBER *ppnum, IN int fmt );
  328. // returns a text representation of a (*pa)
  329. extern TCHAR *putrat(OUT int* pcchNum, IN OUT PRAT *pa, IN unsigned long nRadix, IN int fmt );
  330. extern long longpow( IN unsigned long nRadix, IN long power );
  331. extern long numtolong( IN PNUMBER pnum, IN unsigned long nRadix );
  332. extern long rattolong( IN PRAT prat );
  333. extern PNUMBER _createnum( IN long size ); // returns an empty number structure with size digits
  334. extern PNUMBER nRadixxtonum( IN PNUMBER a, IN unsigned long nRadix );
  335. extern PNUMBER binomial( IN long lroot, IN PNUMBER digitnum, IN PNUMBER c, IN PLINKEDLIST pll, IN unsigned long nRadix );
  336. extern PNUMBER gcd( IN PNUMBER a, IN PNUMBER b );
  337. extern PNUMBER innum( IN LPTSTR buffer ); // takes a text representation of a number and returns a number.
  338. // takes a text representation of a number as a mantissa with sign and an exponent with sign.
  339. extern PRAT inrat( IN BOOL fMantIsNeg, IN LPTSTR pszMant, IN BOOL fExpIsNeg, IN LPTSTR pszExp );
  340. extern PNUMBER longfactnum( IN long inlong, IN unsigned long nRadix );
  341. extern PNUMBER longprodnum( IN long start, IN long stop, IN unsigned long nRadix );
  342. extern PNUMBER longtonum( IN long inlong, IN unsigned long nRadix );
  343. extern PNUMBER numtonRadixx( IN PNUMBER a, IN unsigned long nRadix, IN long ratio );
  344. // creates a empty/undefined rational representation (p/q)
  345. extern PRAT _createrat( void );
  346. // returns a new rat structure with the acos of x->p/x->q taking into account
  347. // angle type
  348. extern void acosanglerat( IN OUT PRAT *px, IN ANGLE_TYPE angletype );
  349. // returns a new rat structure with the acosh of x->p/x->q
  350. extern void acoshrat( IN OUT PRAT *px );
  351. // returns a new rat structure with the acos of x->p/x->q
  352. extern void acosrat( IN OUT PRAT *px );
  353. // returns a new rat structure with the asin of x->p/x->q taking into account
  354. // angle type
  355. extern void asinanglerat( IN OUT PRAT *px, IN ANGLE_TYPE angletype );
  356. extern void asinhrat( IN OUT PRAT *px );
  357. // returns a new rat structure with the asinh of x->p/x->q
  358. // returns a new rat structure with the asin of x->p/x->q
  359. extern void asinrat( IN OUT PRAT *px );
  360. // returns a new rat structure with the atan of x->p/x->q taking into account
  361. // angle type
  362. extern void atananglerat( IN OUT PRAT *px, IN ANGLE_TYPE angletype );
  363. // returns a new rat structure with the atanh of x->p/x->q
  364. extern void atanhrat( IN OUT PRAT *px );
  365. // returns a new rat structure with the atan of x->p/x->q
  366. extern void atanrat( IN OUT PRAT *px );
  367. // returns a new rat structure with the atan2 of x->p/x->q, y->p/y->q
  368. extern void atan2rat( IN OUT PRAT *py, IN PRAT y );
  369. // returns a new rat structure with the cosh of x->p/x->q
  370. extern void coshrat( IN OUT PRAT *px );
  371. // returns a new rat structure with the cos of x->p/x->q
  372. extern void cosrat( IN OUT PRAT *px );
  373. // returns a new rat structure with the cos of x->p/x->q taking into account
  374. // angle type
  375. extern void cosanglerat( IN OUT PRAT *px, IN ANGLE_TYPE angletype );
  376. // returns a new rat structure with the exp of x->p/x->q this should not be called explicitly.
  377. extern void _exprat( IN OUT PRAT *px );
  378. // returns a new rat structure with the exp of x->p/x->q
  379. extern void exprat( IN OUT PRAT *px );
  380. // returns a new rat structure with the log base 10 of x->p/x->q
  381. extern void log10rat( IN OUT PRAT *px );
  382. // returns a new rat structure with the natural log of x->p/x->q
  383. extern void lograt( IN OUT PRAT *px );
  384. extern PRAT longtorat( IN long inlong );
  385. extern PRAT numtorat( IN PNUMBER pin, IN unsigned long nRadix );
  386. extern PRAT realtorat( IN double real );
  387. extern void sinhrat( IN OUT PRAT *px );
  388. extern void sinrat( IN OUT PRAT *px );
  389. // returns a new rat structure with the sin of x->p/x->q taking into account
  390. // angle type
  391. extern void sinanglerat( IN OUT PRAT *px, IN ANGLE_TYPE angletype );
  392. extern void tanhrat( IN OUT PRAT *px );
  393. extern void tanrat( IN OUT PRAT *px );
  394. // returns a new rat structure with the tan of x->p/x->q taking into account
  395. // angle type
  396. extern void tananglerat( IN OUT PRAT *px, IN ANGLE_TYPE angletype );
  397. extern void _destroynum( IN PNUMBER pnum );
  398. extern void _destroyrat( IN PRAT prat );
  399. extern void addnum( IN OUT PNUMBER *pa, IN PNUMBER b, unsigned long nRadix );
  400. extern void addrat( IN OUT PRAT *pa, IN PRAT b );
  401. extern void andrat( IN OUT PRAT *pa, IN PRAT b );
  402. extern void const_init( void );
  403. extern void divnum( IN OUT PNUMBER *pa, IN PNUMBER b, IN unsigned long nRadix );
  404. extern void divnumx( IN OUT PNUMBER *pa, IN PNUMBER b );
  405. extern void divrat( IN OUT PRAT *pa, IN PRAT b );
  406. extern void fracrat( IN OUT PRAT *pa );
  407. extern void factrat( IN OUT PRAT *pa );
  408. extern void modrat( IN OUT PRAT *pa, IN PRAT b );
  409. extern void gcdrat( IN OUT PRAT *pa );
  410. extern void intrat( IN OUT PRAT *px);
  411. extern void mulnum( IN OUT PNUMBER *pa, IN PNUMBER b, IN unsigned long nRadix );
  412. extern void mulnumx( IN OUT PNUMBER *pa, IN PNUMBER b );
  413. extern void mulrat( IN OUT PRAT *pa, IN PRAT b );
  414. extern void numpowlong( IN OUT PNUMBER *proot, IN long power, IN unsigned long nRadix );
  415. extern void numpowlongx( IN OUT PNUMBER *proot, IN long power );
  416. extern void orrat( IN OUT PRAT *pa, IN PRAT b );
  417. extern void powrat( IN OUT PRAT *pa, IN PRAT b );
  418. extern void ratpowlong( IN OUT PRAT *proot, IN long power );
  419. extern void remnum( IN OUT PNUMBER *pa, IN PNUMBER b, IN long nRadix );
  420. extern void rootnum( IN OUT PNUMBER *pa, IN PNUMBER b, IN unsigned long nRadix );
  421. extern void rootrat( IN OUT PRAT *pa, IN PRAT b );
  422. extern void scale2pi( IN OUT PRAT *px );
  423. extern void scale( IN OUT PRAT *px, IN PRAT scalefact );
  424. extern void subrat( IN OUT PRAT *pa, IN PRAT b );
  425. extern void xorrat( IN OUT PRAT *pa, IN PRAT b );
  426. extern void lshrat( IN OUT PRAT *pa, IN PRAT b );
  427. extern void rshrat( IN OUT PRAT *pa, IN PRAT b );
  428. extern BOOL rat_equ( IN PRAT a, IN PRAT b );
  429. extern BOOL rat_neq( IN PRAT a, IN PRAT b );
  430. extern BOOL rat_gt( IN PRAT a, IN PRAT b );
  431. extern BOOL rat_ge( IN PRAT a, IN PRAT b );
  432. extern BOOL rat_lt( IN PRAT a, IN PRAT b );
  433. extern BOOL rat_le( IN PRAT a, IN PRAT b );
  434. extern void inbetween( IN PRAT *px, IN PRAT range );
  435. extern DWORDLONG __inline Mul32x32( IN DWORD a, IN DWORD b );
  436. //extern DWORDLONG __inline __fastcall Shr32xbase( IN DWORDLONG a );
  437. extern void factnum( IN OUT PLINKEDLIST *ppllfact, PNUMBER pnum );
  438. extern void trimit( IN OUT PRAT *px );