The LARD Arbitrary Precision Integer Package: mpint

Introduced primarily to help convert programs from the language Balsa to LARD, the mpint library provides an interface to the GNU gmp library to LARD.

The gmp library provides support for arithmetic and logical operations on arbitrarily large integers. Providing an interface to gmp from LARD has proved much easier than providing native bignum support written in either LARD or icode. Serious users are strongly urged to read the documentation for this library before making use of this library.

Arbitrary precision integers are represented by the type mpint:

	mpint : type .

Values of this type are just pointers to GNU gmp mpz_t objects in the interpreter's memory space. The user must undertake their own store management on mpints as LARD has no support for garbage collection or any other sort of proper `object like' values for that matter. This form of explicit pointer management is somewhat different to the reference counting used by string library and is equally distasteful, I make no apologies.

Easy to manage systems making complete use of mpints can be constructed by wrapping the objects up in a new type, copying values on variable reads (by defining a replacement for read) and overloading the assignment operator. If all normal functions then consume (i.e. destroy) their arguments simple, if not particularly efficient, explicit store management can be achieved.

Declarations, Initialisation, Finalisation, Store Management

A quick example:

	a : var(mpint) .
	a := mpint_init ;
	printmpint (a) ;
	mpint_clear (a)

Most functions with names starting with mpint_ are direct mappings of the gmp mpz_ functions into LARD functions. Here mpint_init combines allocation of space for an mpint and calling the gmp mpz_init function. So, mpint_init provides fresh mpints (which also happen to be initialised to 0). The call to printmpint prints the newly allocated mpint to standard output in decimal. Many of the integer I/O and string conversion functions are overloaded for use of mpints. A final call to mpint_clear surrenders the object to the store manager (== calls free(3)). No further use of the value in the variable a can be made after the call to mpint_clear unless a new value is assigned to it.

N.B. Assignment just copies the pointer to the underlying mpz_t. To copy an existing mpint into an uninitialised variable use the function mpint_copy or to copy a value from one mpint to an *initialised* mpint use mpint_set. Also note that although mpints are almost always passed by value they are pointers and so their underlying object can still be modified by the bodies of functions taking val arguments. Some example initialisations/copies:

	b : var(mpint) .
	c : var(mpint) .
	d : var(mpint) .
	b := mpint_init ; /* A new mpint */
	c := s2mpint ("4356") ; /* Make a new mpint with value 4356 */
	d := mpint_copy (c) ; /* d need not be initialised */
	mpint_set (c, b) ; /* c *must* be initialised (just like mpz_set) */

The complete set of initialisation and setting functions available is:

I/O Functions

Two sets of I/O functions are provided by mpint. One set that mirror the libgmp mpz_{out,inp}_{str,raw} functions using LARD tfile file descriptors and a consistent argument ordering. And another set of `user functions' which mirror the integer I/O operations already present in LARD. None of these functions consume their mpint arguments.

Arithmetic/Logical Functions

As with I/O functions, there are two groups of arithmetic/logical operations. The first group includes mpint_{add,add_ui,sub,sub_ui,mul,mul_ui...} with *all* the mpz_ arithmetic and 2s complement bitwise operations from libgmp included. The prototypes for these functions are too boring to be included and these functions are intended to be used to implement user level functions. Oh yeah, they don't consume their arguments and expect their `return' arguments to be pre-initialised.

The second group are overloaded versions of the operations:

unary -, +, -, *, /, mod, abs, min, max, not, and, or, <<, >>, bitsdiff, <, <=, =, !=, >=, >

These consume their mpint arguments to make constructing complicated expression easier. Overloadings are defined for operations purely on mpints and also from mixtures of mpint and int arguments.

Integer and String Conversion Functions

Various integer <=> mpint and string <=> mpint functions are implemented. None of the functions consume their mpint arguments. Most of the string operations are overloadings of integer operations. For more flexibility user the mpint_ versions and the formatdata function:

Bit-field Functions

Overloaded versions of the integer bit-field extraction operator mpint`[`range`]` (which consumes its mpint argument), the bit extraction operator mpint`[`int`]` (which doesn't) and the prefix bitmask, bitfield, setbit and signextend functions (which also don't consume their arguments) are provided. All bit indices and ranges are represented by ints and range(int)s respectively.

Miscellaneous Notes

The mpint_cmp... functions return a value of type mpint_cmp_t instead of the constants -1, 0 and 1. Instead one of the symbolic constants cmp_less_than, cmp_equal and cmp_greater_than is returned. I suppose this more of an advantage in C where expressions like if (! mpz_cmp (a, b)) is the confusing mpint equality operation.

BTW. Mine's a pint.