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