.TH "libmp" "" "" Library
.PC "Library for multiple-precision mathematics"
.B /usr/lib/libmp.a
.PP
.II "library^multiple-precision mathematics"
.II "mathematics^multiple-precision"
The \*(CO library
.BR libmp
contains routines that allow you to perform multiple-precision arithmetic.
These functions manipulate a data structure called a
.BR mint ,
or ``multiple-precision integer,''
which the header file
.B mprec.h
defines as follows:
.DM
typedef struct {
	unsigned len;
	char *val;
} mint;
.DE
.PP
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.
.PP
The following gives the multiple-precision routines:
.LB
\fBgcd()\fR	Set variable to greatest common divisor
\fBispos()\fR	Return if variable is positive or negative
\fBitom()\fR	Create a multiple-precision integer
\fBmadd()\fR	Add multiple-precision integers
\fBmcmp()\fR	Compare multiple-precision integers
\fBmcopy()\fR	Copy a multiple-precision integer
\fBmdiv()\fR	Divide multiple-precision integers
\fBmin()\fR	Read multiple-precision integer from stdin
\fBminit()\fR	Condition global or auto multiple-precision integer
\fBmintfr()\fR	Free a multiple-precision integer
\fBmitom()\fR	Reinitialize a multiple-precision integer
\fBmneg()\fR	Negate multiple-precision integer
\fBmout()\fR	Write multiple-precision integer to stdout
\fBmsqrt()\fR	Compute square root of multiple-precision integer
\fBmsub()\fR	Subtract multiple-precision integers
\fBmtoi()\fR	Convert multiple-precision integer to integer
\fBmtos()\fR	Convert multiple-precision integer to string
\fBmult()\fR	Multiply multiple-precision integers
\fBmvfree()\fR	Free multiple-precision integer
\fBpow()\fR	Raise multiple-precision integer to power
\fBrpow()\fR	Raise multiple-precision integer to power
\fBsdiv()\fR	Divide multiple-precision integers
\fBsmult()\fR	Multiply multiple-precision integers
\fBspow()\fR	Raise multiple-precision integer to power
\fBxgcd()\fR	Extended greatest-common-divisor function
\fBzerop()\fR	Indicate if multi-precision integer is zero
.PP
.B itom()
creates a new
.BR mint ,
initializes it to the signed integer value
.IR n ,
and returns a pointer to it.
Storage used by a
.B mint
created with
.B itom
may be reclaimed using
.BR mintfr() .
.PP
A
.B mint
that already exists may be reinitialized by
.BR mitom() ,
which sets
.I a
to the value
.IR n .
If the
.B mint
was declared as a global or automatic variable, it
must be conditioned before first use by
.BR minit() ,
which prevents garbage values in the
.B mint
structure from causing chaos.
A
.B mint
conditioned by
.B minit()
has no value; however, it may be used to receive
the result of an operation.
For
.BR mint s
automatic to a function,
.B mvfree()
should be used before the function is exited
to free the storage used by the
.B val
field of the
.B mint
structure.
Otherwise, this storage will never be reclaimed.
.PP
.BR madd (),
.BR msub() ,
and
.B mult()
set
.I c
to the sum,
difference, or product of
.I a
and
.I b.
.B mdiv
divides
.I a
by
.I b
and writes the quotient and remainder in
.I q
and
.I r.
.I b
must not be zero.
The results of the operation are defined by the following conditions:
.IP \fB1.\fR 0.3i
\fIa\^\fR=\fIq\^\fR*\fIb\^\fR+\fIr\^\fR
.IP \fB2.\fR
The sign of \fIr\fR equals the sign of
.I q
.IP \fB3.\fR
The absolute value of
.I r
< the absolute value of
.IR b .
.PP
.B smult()
is like
.BR mult() ,
except the second argument is an integer in the range
0 \(<= \fIn\fR \(<= 127.
.B sdiv()
is like
.BR mdiv() ,
except the second argument is an integer in the range
1 \(<= \fIn\fR \(<= 128, and the remainder argument points to an
.B int
instead of a
.BR mint() .
.PP
.B pow()
sets
.I c
to
.I a
raised to the
.I b
power reduced modulo
.IR m .
.B rpow()
sets
.I c
to
.I a
raised to the
.I b
power.
.B spow()
is like
.BR rpow() ,
except the exponent is an integer.
In no case may the exponent be negative.
.PP
.B mcopy()
sets
.I b
equal to
.IR a .
.B mneg()
sets
.I b
equal to negative
.I a.
.PP
.B msqrt()
sets
.I b
to the integral portion of the positive square root of
.IR a ;
.I r
is set to the remainder.
.I a
must not be negative.
The result of the operation is defined by the condition
.DS
	\fIa\fR = \fIb\fR * \fIb\fR + \fIr\fR
.DE
.PP
.B gcd()
sets
.I c
to the greatest common divisor of
.I a
and
.I b.
.B xgcd()
is an extended gcd routine that
sets
.I g
to the greatest common divisor of
.I a
and
.I b,
and
sets
.I r
and
.I s
so the relation
.DS
	\fIg \fB= \fIa\fB * \fIr\fB + \fIb\fB * \fIs\fR
.DE
.PP
holds.
For
.BR xgcd() ,
.I r,
.I s
and
.I g
must all be distinct.
.PP
.BR mint s
may be compared with
.BR mcmp() ,
which returns a signed integer less than, equal to, or greater than zero
according to whether
.I a
is less than, equal to, or greater than
.I b.
.B ispos()
returns true (nonzero) if
.I a
is not negative,
false (zero) if
.I a
is negative.
.B zerop
returns true if
.I a
is zero, false otherwise.
.PP
.B mtoi()
returns an integer equal to the value of
.IR a .
.I a
should be in the allowable range for a signed integer.
.PP
The external integers
.B ibase
and
.B obase
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).
.B min
reads a
.B mint
in base
.B ibase
from the standard input and sets
.I a
to that value.
Leading blanks and an optional leading minus sign are allowed;
the number is terminated by the first non-legal digit.
.B mout()
outputs
.I a
on the standard output in base
.B obase.
.B mtos()
performs the same conversion as
.BR mout() ,
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
.BR malloc() ,
and may be freed by
.BR free() .
.PP
.B mzero()
and
.B mone()
point to
.BR mint s
with values zero and one.
.B mminint()
and
.B mmaxint()
point to
.BR mint s
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.
.PP
All the necessary declarations
for these constants and for the library functions
are contained in the header file
.BR mprec.h .
They need not be repeated.
.PP
To link
.B libmp
modules into an executable object,
use the argument
.B -lmp
at the end of the
.B cc
command.
.SH Example
The following example converts a string into a multi-precision integer.
.DM
#include <stdio.h>
#include <mprec.h>
#include <ctype.h>
.DE
.DM
/*
 * "ibase" is an int which contains the input base used by "stom".
 * It should be between 2 and 16.
 */
int ibase = 10;
.DE
.DM
/*
 * 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;
.DE
.DM
	mcopy(mzero, &number);	/* set number to zero */
	if ((ch = *s) == '-') {	/* skip leading '-' */
		mifl = 1;
		ch = *++s;
	}
.DE
.DM
	/* 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;
	}
.DE
.DM
	if (mifl)	/* adjust sign of a "number" */
		mneg(&number, &number);
	return(&number);
}
.DE
.DM
/* simple test for "stom" */
main()
{
	char	buffer[80];	
.DE
.DM
	printf("Input string ? ");
	gets(buffer);
	mout(stom(buffer)); /* Print in stdout multiple-precision int */
}
.DE
.SH Files
.nf
.B <mprec.h>
.B /usr/lib/libmp.a
.SH "See Also"
.Xr "bc," bc
.Xr "dc," dc
.Xr "libraries," libraries
.Xr "malloc()," malloc
.Xr "mprec.h" mprec.h
.SH Diagnostics
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.
