2.9BSD/usr/man/cat3/ape.3x
APE(3X) UNIX Programmer's Manual APE(3X)
NAME
ape - arbitrary precision integer arithmetic routines
SYNOPSIS
#include <ape.h>
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