\subsubsection{Idea}

Combinatorics problems often require arbitrary precision arithmetic;
this is the case e.g. with the graph enumeration problem that we
present in the next recipe. We need an efficient Objective C wrapper
class that encapsulates the GMP integer data structure. This is what
{\tt  GMPInt} is all about.

\subsubsection{Implementation}

The class {\tt GMPInt} is a wrapper class whose sole instance variable
holds a GMP Integer.

\begin{lstlisting}{}
#include <Foundation/Foundation.h>
#include <gmp.h>

@interface GMPInt : NSObject
{
    mpz_t value;
}
\end{lstlisting}

The class knows how to manufacture objects for the values zero and
one and it can compute the factorial of an {\tt unsigned long int}.

\begin{lstlisting}{}
+ (GMPInt *)zeroObj;
+ (GMPInt *)oneObj;

+ (GMPInt *)factorialUI:(unsigned long)op;
\end{lstlisting}

There are two factory methods, which use a signed long integer or a GMP
integer.

\begin{lstlisting}{}
+ (GMPInt *)IntWithSI:(signed long)lval;
+ (GMPInt *)IntWithValue:(mpz_t)val;
\end{lstlisting}

The basic operations of arithmetic are implemented. All four use the
receiver as the first operand, the argument as the second and return a
{\tt GMPInt} with the value of the result.

\begin{lstlisting}{}
- (GMPInt *)add:(GMPInt *)op;
- (GMPInt *)sub:(GMPInt *)op;
- (GMPInt *)mul:(GMPInt *)op;
- (GMPInt *)div:(GMPInt *)op;
\end{lstlisting}

{\tt GMPInt} instances can raise themselves to a power given by an
unsigned long integer.

\begin{lstlisting}{}
- (GMPInt *)powUI:(unsigned long)op;
\end{lstlisting}

It is important that a {\tt GMPInt} instance be able to represent
itself as a string. This is what {\tt stringValue:} does; we also
implement {\tt description} so that the {\tt \%@} works e.g. in calls
to {\tt NSLog.}

\begin{lstlisting}{}
- (NSString *)stringValue;
- (NSString *)description;
\end{lstlisting}

Two commonly used predicates test for the receiver's value being zero
or one.

\begin{lstlisting}{}
- (BOOL)isZero;
- (BOOL)isOne;
\end{lstlisting}

The arithmetic methods need to get at the GMP integer value of their
second argument; we provide a method for this purpose. We also
implement {\tt dealloc}, so that we can free GMP integers,
i.e. {\tt ``mpz\_t''} values, that are no longer used.

\begin{lstlisting}{}
- (mpz_t *)valPtr;

- (void)dealloc;

@end
\end{lstlisting}

The implementation is straightforward. The methods {\tt zeroObj} and
{\tt oneObj} simply invoke the factory method with the appropriate
argument.

\begin{lstlisting}{}
@implementation GMPInt

+ (GMPInt *)zeroObj
{
    return [GMPInt IntWithSI:0];
}

+ (GMPInt *)oneObj
{
    return [GMPInt IntWithSI:1];
}
\end{lstlisting}

The class method for the factorial of an unsigned long integer
allocates a {\tt GMPInt}, obtains a pointer to its value, initializes
the value (an {\tt mpz\_t}), calls GMP to compute the result and
returns the {\tt GMPInt}.

\begin{lstlisting}{}
+ (GMPInt *)factorialUI:(unsigned long)op
{
    GMPInt *res = [[GMPInt alloc] autorelease];
    mpz_t *rptr = [res valPtr];

    mpz_init(*rptr);
    mpz_fac_ui(*rptr, op);

    return res;
}
\end{lstlisting}

The two factory methods initialize and set the instance variable {\tt
value} from their arguments and put the object into an autorelease
pool. This is important, because a computation may temporarily
allocate a lot of integers and the space they occupy will not be
released if they are not put in an autorelease pool. We'll see more
about garbage collection later on.

\begin{lstlisting}{}
+ (GMPInt *)IntWithSI:(signed long)lval
{
    GMPInt *inst = [GMPInt alloc];
    mpz_t *ptr = [inst valPtr];

    mpz_init_set_si(*ptr, lval);

    AUTORELEASE(inst);
    return inst;
}

+ (GMPInt *)IntWithValue:(mpz_t)val
{
    GMPInt *inst = [GMPInt alloc];
    mpz_t *ptr = [inst valPtr];

    mpz_set(*ptr, val);

    AUTORELEASE(inst);
    return inst;
}
\end{lstlisting}

The method {\tt add} allocates a {\tt GMPInt}, initializes its value,
stores the sum in this value and returns the {\tt GMPInt}.

\begin{lstlisting}{}
- (GMPInt *)add:(GMPInt *)op
{
    GMPInt *res = [[GMPInt alloc] autorelease];
    mpz_t *rptr = [res valPtr];

    mpz_init(*rptr);
    mpz_add(*rptr, value, *[op valPtr]);

    return res;
}
\end{lstlisting}

Subtraction only differs in the {\tt mpz} method that is called.

\begin{lstlisting}{}
- (GMPInt *)sub:(GMPInt *)op
{
    GMPInt *res = [[GMPInt alloc] autorelease];
    mpz_t *rptr = [res valPtr];

    mpz_init(*rptr);
    mpz_sub(*rptr, value, *[op valPtr]);

    return res;
}
\end{lstlisting}

The structure stays the same for multiplication.

\begin{lstlisting}{}
- (GMPInt *)mul:(GMPInt *)op
{
    GMPInt *res = [[GMPInt alloc] autorelease];
    mpz_t *rptr = [res valPtr];

    mpz_init(*rptr);
    mpz_mul(*rptr, value, *[op valPtr]);

    return res;
}
\end{lstlisting}

Division is like multiplication, except that we must choose from
several {\tt mpz} calls according to the rounding style that is to be
used and whether we need the quotient, the remainder or both. We
choose ``truncate'' for our rounding style and we do not compute the
remainder.

\begin{lstlisting}{}
- (GMPInt *)div:(GMPInt *)op
{
    GMPInt *res = [[GMPInt alloc] autorelease];
    mpz_t *rptr = [res valPtr];

    mpz_init(*rptr);
    mpz_tdiv_q(*rptr, value, *[op valPtr]);

    return res;
}
\end{lstlisting}

Exponentiation differs from the preceding methods in that there is no
invocation of {\tt valPtr}, because we may use the argument as is.

\begin{lstlisting}{}
- (GMPInt *)powUI:(unsigned long)op
{
    GMPInt *res = [[GMPInt alloc] autorelease];
    mpz_t *rptr = [res valPtr];

    mpz_init(*rptr);
    mpz_pow_ui(*rptr, value, op);

    return res;
}
\end{lstlisting}

The method {\tt stringValue} returns a string that is a decimal
representation of the receiver. It uses {\tt mpz\_sizeinbase} to
determine the number of digits and takes a possible sign and the
terminating null byte into account. It invokes {\tt mpgz\_get\_str} to
write the decimal representation into a buffer it has allocated for
this purpose and then produces a {\tt NSString} object from the
contents of the buffer, freeing it after the string object is
obtained. The method {\tt description} simply returns the string value
of the receiver.

\begin{lstlisting}{}
- (NSString *)stringValue
{
    NSZone *dz = NSDefaultMallocZone();
    char *buf;
    NSString *res;

    buf = NSZoneMalloc(dz, mpz_sizeinbase(value, 10)+2);
    mpz_get_str(buf, 10, value);
    res = [NSString stringWithCString:buf];
    NSZoneFree(dz, buf);
	
    return res;
}

- (NSString *)description
{
    return [self stringValue];
}
\end{lstlisting}

The predicates that test for zero and one, respectively, work by
calling the {\tt mpz\_comp\_ui} with the appropriate arguments.

\begin{lstlisting}{}
- (BOOL)isZero
{
    return (!mpz_cmp_ui(value, 0) ? YES : NO);
}

- (BOOL)isOne
{
    return (!mpz_cmp_ui(value, 1) ? YES : NO);
}
\end{lstlisting}

The method {\tt valPtr} is used by the arithmetic methods and returns
the address of the {\tt mpz\_t} value in the receiver.

\begin{lstlisting}{}
- (mpz_t *)valPtr
{
    return &value;
}
\end{lstlisting}

The implementation of {\tt GMPInt} concludes with the method {\tt
dealloc}, whose purpose is to free the space that GMP has allocated
for the value of the receiver, since it is no longer needed.

\begin{lstlisting}{}
- (void)dealloc
{
    mpz_clear(value);
    [super dealloc];
}

@end
\end{lstlisting}
