| /* |
| * Arbitrary precision integer math package |
| * |
| * (c) Copyright 1991 by David A. Barrett (barrett@asgard.UUCP) |
| * |
| * Not to be used for profit or distributed in systems sold for profit |
| */ |
| #ifndef BASE |
| typedef unsigned short prefc; /* reference counter type */ |
| typedef prefc *precision; /* this a a private data structure */ |
| extern int pfree(); /* free (private) */ |
| #endif |
| |
| typedef precision *pvector; /* a vector of precision */ |
| typedef pvector *parray; /* 2d array */ |
| |
| /* |
| * Error values passed to errorp |
| */ |
| #define PNOERROR 0 |
| #define PNOMEM 1 |
| #define PREFCOUNT 2 |
| #define PUNDEFINED 3 |
| #define PDOMAIN 4 |
| #define POVERFLOW 5 |
| |
| #define pUndef ((precision) 0) /* An undefined value */ |
| #define pNull ((precision *) 0) |
| |
| #define peq(u, v) (pcmp((u), (v)) == 0) |
| #define pne(u, v) (pcmp((u), (v)) != 0) |
| #define pgt(u, v) (pcmp((u), (v)) > 0) |
| #define plt(u, v) (pcmp((u), (v)) < 0) |
| #define pge(u, v) (pcmp((u), (v)) >= 0) |
| #define ple(u, v) (pcmp((u), (v)) <= 0) |
| |
| #define peqz(u) (pcmpz(u) == 0) |
| #define pnez(u) (pcmpz(u) != 0) |
| #define pltz(u) (pcmpz(u) < 0) |
| #define pgtz(u) (pcmpz(u) > 0) |
| #define plez(u) (pcmpz(u) <= 0) |
| #define pgez(u) (pcmpz(u) >= 0) |
| |
| #define peven(u) (!podd(u)) |
| #define pdiv(u,v) (pdivmod(u,v, (precision *) -1, pNull)) |
| #define pmod(u,v) (pdivmod(u,v, pNull, (precision *) -1)) |
| #define pdivr(u,v,r) (pdivmod(u,v, (precision *) -1, r)) |
| #define pmodq(u,v,q) (pdivmod(u,v, q, (precision *) -1)) |
| |
| /* |
| * Application programs should only use the following definitions; |
| * |
| * pnew, pdestroy, pparm, presult and pset |
| * |
| * Other variants are internal only! |
| * All are side-effect safe except for pparm and presult. |
| * -DDEBUG will enable argument checking for pset and pparm |
| */ |
| |
| /* LLVM - Disable all of the inlining */ |
| #if 0 |
| #ifdef __GNUC__ /* inline is NOT ansii! Sigh. */ |
| #ifndef BWGC |
| extern inline precision pnew(precision u) { (* (prefc *) u)++; return u; } |
| extern inline void pdestroy(precision u) { |
| if (u != pUndef && --(*(prefc *) u) == 0) pfree(u); |
| } |
| extern inline precision pparmq(precision u) { |
| if (u != pUndef) (* (prefc *) u)++; return u; |
| } |
| extern inline precision presult(precision u) { |
| if (u != pUndef) --(*(prefc *) u); return u; |
| } |
| extern inline precision psetq(precision *up, precision v) { |
| precision u = *up; |
| *up = v; |
| if (v != pUndef) (* (prefc *) v)++; |
| if (u != pUndef && --(* (prefc *) u) == 0) pfree(u); |
| return v; |
| } |
| #define pvoid(u) pdestroy(u) |
| #else |
| extern inline precision pnew(precision u) { return u; } |
| extern inline void pdestroy(precision u) {} |
| extern inline precision pparmq(precision u) { return u; } |
| extern inline precision presult(precision u) { return u; } |
| extern inline precision psetq(precision *up, precision v) { |
| precision u = *up; |
| *up = v; |
| return v; |
| } |
| #define pvoid(u) pdestroy(u) |
| #endif |
| #else |
| #ifndef BWGC |
| #define pdestroy(u) (void) ((u)!=pUndef&&--(*(prefc *)(u))==0&&pfree(u)) |
| #define pparmq(u) ((u) != pUndef && (* (prefc *) (u))++, (u)) |
| #define pvoid(u) pdestroyf(u) |
| #else |
| #define pdestroy(u) (void) (0) |
| #define pparmq(u) (u) |
| #define pvoid(u) pdestroyf(u) |
| #endif |
| #endif |
| #else |
| #define pdestroy(u) (void) ((u)!=pUndef&&--(*(prefc *)(u))==0&&pfree(u)) |
| #define pparmq(u) ((u) != pUndef && (* (prefc *) (u))++, (u)) |
| #define pvoid(u) pdestroyf(u) |
| #endif |
| |
| |
| #ifdef PDEBUG |
| #define pset(u, v) psetv(u, v) |
| #define pparm(u) pparmv(u) |
| #else |
| #define pset(u, v) psetq(u, v) |
| #define pparm(u) pparmq(u) |
| #endif |
| |
| #ifdef __STDC__ /* if ANSI compiler */ |
| /* LLVM - Disable all of the inlining */ |
| #if 0 |
| #ifndef __GNUC__ |
| extern precision pnew(precision); /* initialization */ |
| extern precision presult(precision); /* function result */ |
| extern precision psetq(precision *, precision); /* quick assignment */ |
| #endif |
| #else |
| extern precision pnew(precision); /* initialization */ |
| extern precision presult(precision); /* function result */ |
| extern precision psetq(precision *, precision); /* quick assignment */ |
| #endif |
| extern precision psetv(precision *, precision); /* checked assignment */ |
| extern precision pparmv(precision); /* checked parameter */ |
| extern precision pparmf(precision); /* unchecked parameter (fn) */ |
| |
| extern int pcmpz(precision); /* compare to zero */ |
| extern int pcmp(precision, precision); /* compare */ |
| extern int picmp(precision, int); /* single digit cmp */ |
| |
| extern precision padd(precision, precision); /* add */ |
| extern precision psub(precision, precision); /* subtract */ |
| extern precision pmul(precision, precision); /* multiply */ |
| |
| extern precision pdivmod(precision, precision, |
| precision *q, precision *r); |
| |
| extern precision pidiv(precision, int); /* single digit pdiv */ |
| extern int pimod(precision, int); /* single digit pmod */ |
| extern void pidivmod(precision, int, /* single pdivmod */ |
| precision *q, int *r); |
| |
| extern precision pneg(precision); /* negate */ |
| extern precision pabs(precision); /* absolute value */ |
| extern int podd(precision); /* true if odd */ |
| extern precision phalf(precision); /* divide by two */ |
| |
| extern precision pmin(precision, precision); /* minimum value */ |
| extern precision pmax(precision, precision); /* maximum value */ |
| |
| extern precision prand(precision); /* random number generator */ |
| |
| extern precision itop(int); /* int to precision */ |
| extern precision utop(unsigned); /* unsigned to precision */ |
| extern precision ltop(long); /* long to precision */ |
| extern precision ultop(unsigned long); /* unsigned long to precision */ |
| |
| extern int ptoi(precision); /* precision to int */ |
| extern unsigned int ptou(precision); /* precision to unsigned */ |
| extern long ptol(precision); /* precision to long */ |
| extern unsigned long ptoul(precision); /* precision to unsigned long */ |
| |
| extern precision atop(char *); /* ascii to precision */ |
| extern char *ptoa(precision); /* precision to ascii */ |
| |
| extern int btop(precision *result, /* base to precision */ |
| char *src, unsigned size, int *digitmap, unsigned radix); |
| |
| extern int /* precision to base */ |
| ptob(precision, char *result, unsigned size, char *alphabet, unsigned radix); |
| |
| /* |
| * Can't do prototyping for these unless stdio.h has been included |
| */ |
| #ifdef BUFSIZ |
| extern precision fgetp(FILE *stream); /* input precision */ |
| extern int fputp(FILE *stream, precision); /* output precision */ |
| extern int |
| fprintp(FILE *stream, precision, int minWidth); /* output within a field */ |
| #else |
| extern precision fgetp(); /* input precision */ |
| extern int fputp(); /* output precision */ |
| extern int fprintp(); /* output within a field */ |
| #endif |
| |
| extern int putp(precision); /* stdout with '\n' */ |
| |
| extern void pshow(precision); /* display debug info */ |
| extern precision prandnum(); /* debug and profil only */ |
| extern precision pshift(precision, int); /* shift left */ |
| |
| extern precision errorp(int errnum, char *routine, char *message); |
| |
| extern precision pzero, pone, ptwo; /* constants 0, 1, and 2 */ |
| extern precision p_one; /* constant -1 */ |
| |
| extern precision psqrt(precision); /* square root */ |
| extern precision pfactorial(precision); /* factorial */ |
| extern precision pipow(precision, unsigned); /* unsigned int power */ |
| extern precision ppow(precision, precision); /* precision power */ |
| extern precision |
| ppowmod(precision, precision, precision); /* precision power mod m */ |
| extern int plogb(precision, precision); /* log base b of n */ |
| |
| extern precision dtop(double); /* double to precision */ |
| extern double ptod(precision); /* precision to double */ |
| |
| /* |
| * vector operations |
| */ |
| pvector pvundef(pvector, unsigned size); /* local variable entry */ |
| void pvdestroy(pvector, unsigned size); /* local variable exit */ |
| |
| pvector pvalloc(unsigned size); /* pvec allocate */ |
| void pvfree(pvector, unsigned size); /* pvec free */ |
| |
| pvector pvset(pvector, unsigned size, precision value); |
| |
| #else |
| |
| /* |
| * Function versions of above if you still want side effects |
| */ |
| |
| /* LLVM - Disable all of the inlining */ |
| #if 0 |
| #ifndef __GNUC__ |
| extern precision pnew(); /* initialization */ |
| extern precision presult(); /* function result */ |
| extern precision psetq(); /* quick assignment */ |
| #endif |
| #else |
| extern precision pnew(); /* initialization */ |
| extern precision presult(); /* function result */ |
| extern precision psetq(); /* quick assignment */ |
| #endif |
| extern precision psetv(); /* checked assignment */ |
| extern precision pparmv(); /* checked parameter */ |
| extern precision pparmf(); /* unchecked parameter (fn) */ |
| |
| extern int pcmpz(); /* compare to zero */ |
| extern int pcmp(); /* compare */ |
| extern int picmp(); /* single digit compare */ |
| |
| extern precision padd(); /* add */ |
| extern precision psub(); /* subtract */ |
| extern precision pmul(); /* multiply */ |
| |
| extern precision pdivmod(); /* divide/remainder */ |
| extern void pidivmod(); /* single digit divide/remainder */ |
| extern precision pidiv(); /* single digit divide */ |
| extern int pimod(); /* single digit remainder */ |
| extern precision pneg(); /* negate */ |
| extern precision pabs(); /* absolute value */ |
| extern int podd(); /* true if odd */ |
| extern precision phalf(); /* divide by two */ |
| |
| extern precision pmin(); /* minimum value */ |
| extern precision pmax(); /* maximum value */ |
| |
| extern precision prand(); /* random number generator */ |
| |
| extern precision itop(); /* int to precision */ |
| extern precision utop(); /* unsigned to precision */ |
| extern precision ltop(); /* long to precision */ |
| extern precision ultop(); /* unsigned long to precision */ |
| |
| extern int ptoi(); /* precision to int */ |
| extern unsigned int ptou(); /* precision to unsigned */ |
| extern long ptol(); /* precision to long */ |
| extern unsigned long ptoul(); /* precision to unsigned long */ |
| |
| extern precision atop(); /* ascii to precision */ |
| extern char *ptoa(); /* precision to ascii */ |
| |
| extern int btop(); /* base to precision */ |
| extern int ptob(); /* precision to base */ |
| |
| extern precision fgetp(); /* input a precision */ |
| extern int fputp(); /* output a precision */ |
| extern int putp(); /* output precision '\n' to stdout */ |
| extern int fprintp(); /* output a precision within a field */ |
| |
| extern void pshow(); /* display debug info */ |
| extern precision prandnum(); /* for debug and profil only */ |
| extern precision pshift(); /* shift left */ |
| |
| extern precision errorp(); /* user-substitutable error handler */ |
| |
| extern precision pzero, pone, ptwo; /* constants 0, 1, and 2 */ |
| extern precision p_one; /* constant -1 */ |
| |
| extern precision psqrt(); /* square root */ |
| extern precision pfactorial(); /* factorial */ |
| extern precision pipow(); /* unsigned int power */ |
| extern precision ppow(); /* precision power */ |
| extern precision ppowmod(); /* precision power mod m */ |
| extern int plogb(); /* log base b of n */ |
| |
| extern precision dtop(); /* double to precision */ |
| extern double ptod(); /* precision to double */ |
| |
| /* |
| * vector operations |
| */ |
| pvector pvundef(); /* local variable entry */ |
| void pvdestroy(); /* local variable exit */ |
| pvector pvalloc(); /* pvec allocate */ |
| void pvfree(); /* pvec free */ |
| pvector pvset(); /* set each element to scaler */ |
| |
| #endif |