APE(3X) UNIX Programmer's Manual APE(3X) NAME ape - arbitrary precision integer arithmetic routines SYNOPSIS #include cc ... -lape f77 ... -lape DESCRIPTION The _a_p_e library is a set of routines for arbitrary precision integral arithmetic which may be called by either C or F77 programs. The routines work on the structure MINT (``multiprecision integer'') defined by typedef struct mint { int len; short *val; } MINT, *PMINT; The member _l_e_n is an integer whose sign is the sign of the number represented, and whose magnitude is the number of words (short integers) needed to store it. The (absolute value of) the number itself is stored base 2^15 as an array of short ints pointed to by _v_a_l. Space for this array is managed by calls to _m_a_l_l_o_c(3) and _f_r_e_e. The size of the numbers representable is limited only by the amount of core available; on a PDP-11/45, numbers of 40,000 digits have been successfully dealt with. The routines themselves may be grouped into four categories: INITIALIZATION AND REMOVAL MINT pointers (PMINTs) must be initialized before they can be used by the other routines. Methods for doing this include: new(pa) PMINT *pa; PMINT shtom(sn) short sn; PMINT itom(n) int n; PMINT ltom(ln) long ln; PMINT stom(s) char *s; _N_e_w(&_a) creates a zero MINT which _a points to. The other functions return pointers to MINTs with values equal to their arguments (or to the numeric equivalent of its argu- ment for _s_t_o_m). _S_t_o_m follows the usual C conventions for determining the input base. Printed 8/1/83 1 APE(3X) UNIX Programmer's Manual APE(3X) For freeing storage, two routines are provided: xfree(a) afree(a) PMINT a; _X_f_r_e_e(_a) frees what _a->_v_a_l points to, zeroing _a; _a_f_r_e_e(_a) also frees what _a points to. ARITHMETIC For the following conceptual descriptions, assume these type declarations: PMINT a,b,c,d,q,r; int m,n; long ln; short *R; _R_o_u_t_i_n_e _R_e_s_u_l_t madd(a,b,c) c = a + b msub(a,b,c) c = a - b mult(a,b,c) c = a * b sdiv(a,m,q,R) q = a / m; R = a mod m mdiv(a,b,q,r) q = a / b; r = a mod b gcd(a,b,c) c = gcd(a,b) reciprocal(a,n,b) b = 10^n / a msqrt(a,b,r) b = sqrt(a); r = a - b*b [r's length is returned] pow(a,b,c,d) d = a^b mod c rpow(a,n,b) b = a^n lpow(n,ln,b) b = n^ln In all cases, calls like _m_a_d_d(_a,_b,_a) are allowed and give the expected results. The routines dealing with ints will all work properly no matter what the relationship between short and int except _s_d_i_v which needs the int _m to be no larger than the largest short. _R_e_c_i_p_r_o_c_a_l is the closest thing provided to decimal fractions. Comparisons may be done with the function _m_c_m_p. _M_c_m_p(_a,_b) returns something positive if _a>_b, negative if _a<_b, and zero if _a=_b. INPUT AND OUTPUT The following routines do input and output: PMINT a; int n; /* must have _n > 1 */ FILE *f; char *s; m_in(a,n,f) input a number base _n from file _f into _a Printed 8/1/83 2 APE(3X) UNIX Programmer's Manual APE(3X) sm_in(a,n,s) input a number base _n from string _s into _a m_out(a,n,f) output _a base _n onto file _f sm_out(a,n,s) output _a base _n onto string _s _M__i_n returns 0 on normal termination, and EOF when the end of the input file is reached. Special versions of these routines are provided for bases 8 and 10. They are: PMINT a; FILE *f; Base 8 om_in(a,f) omin(a) [f=stdin] om_out(a,f) omout(a) [f=stdout] Base 10 fmin(a,f) minput(a) [f=stdin] fmout(a,f) mout(a) [f=stdout] F77 USAGE ``Frontend'' subroutines are provided to allow F77 programs to use the _a_p_e routines. The calling program's integers are cast into PMINTs by these subroutines and then passed to the appropriate _a_p_e routine. The names and syntax of these subroutines are generally the same as their C counterparts. Exceptions are: _f_7_7 _v_e_r_s_i_o_n _C _v_e_r_s_i_o_n integer n,a int n; PMINT a; character*M s char s[M]; call new(a) new(&a); call itom(n,a) a = itom(n); call stom(s,a) a = stom(s); call minput(a,n) n = minput(a); Printed 8/1/83 3 APE(3X) UNIX Programmer's Manual APE(3X) call omin(a,n) n = omin(a); call mout(a) mout(a); call omout(a) mout(a); (no other I/O routines are provided) Subroutines are also provided for conversions between the MINT structure and the Fortran-manipulable version of an integer and an array of integer*2's: integer a, length [_a represents a PMINT] integer*2 vector(N) [must have abs(length) .le. N] call mtovec(a,length,vector) results in: length = a->len for i = 1 to abs(length) vector(i) = a->val[i-1] call vectom(length,vector,a) results in: a->len = length for i = 1 to abs(length) a->val[i-1] = vector(i) The latter is actually a method of initialization. FILES /usr/include/ape.h include file /usr/lib/libape.a object code library SEE ALSO bc(1), dc(1), malloc(3), mp(3X) DIAGNOSTICS Improper operations and running out of memory produce self- explanatory messages and gratuitous core dumps. BUGS Input bases should be <= 35. Octal input is slower than it need be. Syntax is odd and storage management is a pain. AUTHOR Mark Carson Printed 8/1/83 4