lliibbmmpp -- Library

Library for multiple-precision mathematics
/uussrr/lliibb/lliibbmmpp.aa

The  COHERENT library  lliibbmmpp contains  routines that  allow you  to perform
multiple-precision arithmetic.  These functions manipulate a data structure
called  a mmiinntt,  or ``multiple-precision integer,''  which the  header file
mmpprreecc.hh defines as follows:

typedef struct {
    unsigned len;
    char *val;
} mint;

You should  not depend on  the details of  this structure, because  on some
machines  a different  representation  may be  more  efficient.  Using  the
listed functions is always safe.

The following gives the multiple-precision routines:

ggccdd()..........Set variable to greatest common divisor
iissppooss()........Return if variable is positive or negative
iittoomm().........Create a multiple-precision integer
mmaadddd().........Add multiple-precision integers
mmccmmpp().........Compare multiple-precision integers
mmccooppyy()........Copy a multiple-precision integer
mmddiivv().........Divide multiple-precision integers
mmiinn()..........Read multiple-precision integer from stdin
mmiinniitt()........Condition global or auto multiple-precision integer
mmiinnttffrr().......Free a multiple-precision integer
mmiittoomm()........Reinitialize a multiple-precision integer
mmnneegg().........Negate multiple-precision integer
mmoouutt().........Write multiple-precision integer to stdout
mmssqqrrtt()........Compute square root of multiple-precision integer
mmssuubb().........Subtract multiple-precision integers
mmttooii().........Convert multiple-precision integer to integer
mmttooss().........Convert multiple-precision integer to string
mmuulltt().........Multiply multiple-precision integers
mmvvffrreeee().......Free multiple-precision integer
ppooww()..........Raise multiple-precision integer to power
rrppooww().........Raise multiple-precision integer to power
ssddiivv().........Divide multiple-precision integers
ssmmuulltt()........Multiply multiple-precision integers
ssppooww().........Raise multiple-precision integer to power
xxggccdd().........Extended greatest-common-divisor function
zzeerroopp()........Indicate if multi-precision integer is zero

iittoomm() creates  a new mmiinntt, initializes  it to the signed  integer value _n,
and returns a pointer to it.   Storage used by a mmiinntt created with iittoomm may
be reclaimed using mmiinnttffrr().

A mmiinntt that already exists may be reinitialized by mmiittoomm(), which sets _a to
the value _n. If the mmiinntt was declared as a global or automatic variable, it
must be  conditioned before  first use  by mmiinniitt(), which  prevents garbage
values in  the mmiinntt  structure from causing  chaos.  A mmiinntt  conditioned by
mmiinniitt() has no  value; however, it may be used  to receive the result of an
operation.   For mmiinntts  automatic to  a function,  mmvvffrreeee() should  be used
before the function is exited to  free the storage used by the vvaall field of
the mmiinntt structure.  Otherwise, this storage will never be reclaimed.

mmaadddd(), mmssuubb(),  and mmuulltt() set _c  to the sum, difference,  or product of _a
and _b. mmddiivv  divides _a by _b and writes  the quotient and remainder in _q and
_r. _b  must not be  zero.  The results  of the operation are  defined by the
following conditions:

11. _a=_q*_b+_r

22. The sign of _r equals the sign of _q

33. The absolute value of _r < the absolute value of _b.

ssmmuulltt() is  like mmuulltt(), except  the second argument  is an integer  in the
range 0 <_ _n <_ 127.  ssddiivv() is like mmddiivv(), except the second argument is an
integer in the range 1 <_ _n <_ 128,  and the remainder argument  points to an
iinntt instead of a mmiinntt().

ppooww() sets _c to _a raised  to the _b power reduced modulo _m. rrppooww() sets _c to
_a raised to the _b power.   ssppooww() is like rrppooww(), except the exponent is an
integer.  In no case may the exponent be negative.

mmccooppyy() sets _b equal to _a. mmnneegg() sets _b equal to negative _a.

mmssqqrrtt() sets _b to the integral  portion of the positive square root of _a; _r
is  set to  the remainder.   _a  must not  be negative.   The result  of the
operation is defined by the condition

    _a = _b * _b + _r

ggccdd()  sets _c  to the  greatest common  divisor of  _a and  _b. xxggccdd()  is an
extended gcd routine that sets _g to the greatest common divisor of _a and _b,
and sets _r and _s so the relation

    _g = _a * _r + _b * _s

holds.  For xxggccdd(), _r, _s and _g must all be distinct.

mmiinntts  may be  compared with  mmccmmpp(), which returns  a signed  integer less
than, equal to,  or greater than zero according to  whether _a is less than,
equal to,  or greater than  _b. iissppooss() returns  true (nonzero) if  _a is not
negative, false (zero) if _a is  negative.  zzeerroopp returns true if _a is zero,
false otherwise.

mmttooii()  returns an integer  equal to  the value  of _a. _a  should be  in the
allowable range for a signed integer.

The external  integers iibbaassee and oobbaassee govern the  I/O and ASCII conversion
routines.  Allowable  bases run from  two to 16.  Permissible  digits are 0
through 9 and A through F  (lower-case letters are not allowed).  mmiinn reads
a mmiinntt  in base  iibbaassee from the  standard input and  sets _a to  that value.
Leading blanks  and an optional leading minus sign  are allowed; the number
is  terminated by  the  first non-legal  digit.   mmoouutt() outputs  _a on  the
standard  output in  base  oobbaassee. mmttooss()  performs the  same conversion  as
mmoouutt(), but  the result is  placed in a  character string instead  of being
output;  a pointer  to  the string  is  returned.  The  string is  actually
allocated by mmaalllloocc(), and may be freed by ffrreeee().

mmzzeerroo() and mmoonnee() point to mmiinntts  with values zero and one.  mmmmiinniinntt() and
mmmmaaxxiinntt() point  to mmiinntts  containing the  minimum and maximum  values that
will fit in a signed integer.   These constants should never be used as the
result of an operation.

All  the necessary  declarations for  these constants  and for  the library
functions  are contained  in  the header  file  mmpprreecc.hh. They  need not  be
repeated.

To link lliibbmmpp  modules into an executable object, use  the argument -llmmpp at
the end of the cccc command.

_E_x_a_m_p_l_e
The following example converts a string into a multi-precision integer.

#include <stdio.h>
#include <mprec.h>
#include <ctype.h>

/*
 * "ibase" is an int which contains the input base used by "stom".
 * It should be between 2 and 16.
 */
int ibase = 10;

/*
 * stom() reads in a number in base ibase from string 'a' and returns
 * pointer to multiple-precision integer.
 */
mint *stom(s)
register char *s;
{
    char cval;
    mint c = {1, &cval};
    register int ch;
    char mifl = 0;  /* leading minus flag */
    static mint number;

    mcopy(mzero, &number);  /* set number to zero */
    if ((ch = *s) == '-') { /* skip leading '-' */
        mifl = 1;
        ch = *++s;
    }

    /* scan thru string 's', building result in "number" */
    while (isascii(ch) && isdigit(ch)) {
        cval = (isdigit(ch) ? ch - '0': ch - 'A');
        smult(&number, ibase, &number);
        madd(&number, &c, &number);
        ch = *++s;
    }

    if (mifl)   /* adjust sign of a "number" */
        mneg(&number, &number);
    return(&number);
}

/* simple test for "stom" */
main()
{
    char    buffer[80];

    printf("Input string ? ");
    gets(buffer);
    mout(stom(buffer)); /* Print in stdout multiple-precision int */
}

_F_i_l_e_s
<mmpprreecc.hh>
/uussrr/lliibb/lliibbmmpp.aa

_S_e_e _A_l_s_o
bbcc, ddcc, lliibbrraarriieess, mmaalllloocc(), mmpprreecc.hh

_D_i_a_g_n_o_s_t_i_c_s
On any error, such as division  by zero, running out of space or taking the
square root of a negative number,  an appropriate message is printed on the
standard error stream and the program exits with a nonzero status.
