/******************************************************
* Integer.h -- C++ Integer class for the gmp integer library (from the
* GNU project.) Allows you to use the arbitrary precision integers
* from gmp as if they were plain old (int)'s or (long int)'s. Just
* include this file in your source code. Example main():
*
* #include "Integer.h"
* int main(int argc, char **argv) {
* Integer a, b, c;
*
* a = argv[1]; // automaticaly converts a string
* b = argv[2]; // into an Integer.
* c = a*b;
* cout << a << " x " << b << " = " << c << endl;
* }
*
********
* To Do:
* Rewrite all additions to check for signed (int)s (Done! with 000605)
* ChangeLog:
* 970304 - Created -- Paul Herman <a540pau@pslc.ucla.edu>
* 980804 - Cleaned up -- Paul Herman <a540pau@pslc.ucla.edu>
* 000605 - bug fixes -- Paul Herman <pherman@frenchfries.net>
*******************************************************/
/***************************** BEGIN ********************************/
#include <stdlib.h>
#ifndef FALSE
#define FALSE 0
#endif // FALSE
#ifndef TRUE
#define TRUE 1
#endif // TRUE
#ifndef __GMP_INTEGER_CLASS__
#define __GMP_INTEGER_CLASS__
#include <gmp.h> // provides the mpz integer routines
#include <iostream.h> // for cin & cout istreams & ostreams
#include <time.h> // use time as seed for random numbers
#ifndef ABSmodN
#define ABSmodN(x, n) (x%n) // in gmp lib, (-x)%n = (n-x)%n
#endif // ABSmodN
/**************************** INTEGER ***************************************/
class Integer {
private:
mpz_t _x;
int base;
public:
//
// Constructors
//
Integer(void);
Integer(int a);
Integer(unsigned int a);
Integer(const Integer &a);
Integer(char * a);
Integer(mpz_t a);
//
// Destructor
//
~Integer(void);
//
// Simple access functions
//
int getbase(void);
void setbase(int b);
//
// Casting (changing Integer to another type)
//
operator bool(void); // (bool) i
operator int(void); // (int) i
operator unsigned int(void);// (unsigned int) i
operator float(void); // (float) i
operator double(void); // (double)i
//
// Assignments (Setting Integer equal to something else)
//
void operator =(Integer a); // c = (Integer) a;
void operator =(int a); // c = (int) a;
void operator =(unsigned int a); // c = (unsigned int) a;
void operator =(char *a); // c = a (a string);
void operator =(const char *a); // c = "1231231";
void operator =(mpz_t a); // c = a (a mpz number);
//
// Binary (one sided) operators
//
Integer operator -(void); // c = -a;
bool operator !(void); // c = (bool) (!a)
void operator +=(Integer a); // c += a;
void operator +=(int a); // c += a;
void operator +=(unsigned int a); // c += a;
void operator -=(Integer a); // c -= a;
void operator -=(int a); // c -= a;
void operator -=(unsigned int a); // c -= a;
void operator *=(Integer a); // c *= a;
void operator *=(int a); // c *= a;
void operator *=(unsigned int a); // c *= a;
void operator /=(Integer a); // c /= a;
void operator /=(int a); // c /= a;
void operator /=(unsigned int a); // c /= a;
void operator %=(Integer a); // c %= a;
void operator %=(int a); // c %= a;
void operator ^=(int a); // c ^= a;
// WARNING: No ^ with type (Integer) as exponent
Integer operator ++(void); // c = a++;
Integer operator --(void); // c = a--;
Integer operator ++(int from); // c = ++a;
Integer operator --(int from); // c = --a;
//
// The following operators must be friendly because the are binary
//
friend Integer operator +(Integer a, Integer b); // a + b;
friend Integer operator +(Integer a, int b); // a + b;
friend Integer operator +(int a, Integer b); // a + b;
friend Integer operator -(Integer a, Integer b); // a - b;
friend Integer operator -(Integer a, int b); // a - b;
friend Integer operator -(int a, Integer b); // a - b;
friend Integer operator *(Integer a, Integer b); // a * b;
friend Integer operator *(Integer a, int b); // a * b;
friend Integer operator *(int a, Integer b); // a * b;
friend Integer operator /(Integer a, Integer b); // a / b;
friend Integer operator /(Integer a, int b); // a / b;
friend Integer operator /(int a, Integer b); // a / b;
friend Integer operator %(Integer a, Integer b); // a % b;
friend Integer operator %(Integer a, int b); // a % b;
friend Integer operator %(int a, Integer b); // a % b;
friend Integer operator ^(Integer a, int b); // a ^ b;
friend Integer operator &(Integer a, Integer b); // a & b;
friend Integer operator |(Integer a, Integer b); // a | b;
friend bool operator ==(Integer a, Integer b); // (c == a)?
friend bool operator ==(Integer a, int b); // (c == a)?
friend bool operator ==(int a, Integer b); // (c == a)?
friend bool operator !=(Integer a, Integer b); // (c != a)?
friend bool operator !=(Integer a, int b); // (c != a)?
friend bool operator !=(int a, Integer b); // (c != a)?
friend bool operator <(Integer a, Integer b); // (c < a)?
friend bool operator <(Integer a, int b); // (c < a)?
friend bool operator <(int a, Integer b); // (c < a)?
friend bool operator <=(Integer a, Integer b); // (c <= a)?
friend bool operator <=(Integer a, int b); // (c <= a)?
friend bool operator <=(int a, Integer b); // (c <= a)?
friend bool operator >(Integer a, Integer b); // (c > a)?
friend bool operator >(Integer a, int b); // (c > a)?
friend bool operator >(int a, Integer b); // (c > a)?
friend bool operator >=(Integer a, Integer b); // (c >= a)?
friend bool operator >=(Integer a, int b); // (c >= a)?
friend bool operator >=(int a, Integer b); // (c >= a)?
friend ostream& operator <<(ostream &s, Integer a); // cout << a;
friend istream& operator >>(istream &s, Integer &a); // cin >> a;
friend Integer& operator <<(Integer a, int b); // a << b;
friend Integer& operator >>(Integer a, int b); // a >> b;
//
// These functions are friendly to speed up access to the class'
// private parts.
//
friend void Int2a(Integer i, char *string);
friend Integer gcd(Integer a, Integer b);
friend Integer exgcd(Integer a, Integer b, Integer &c, Integer &d);
friend Integer InvModN(Integer a, Integer n);
friend Integer PowModN(Integer base, Integer exp, Integer n);
friend Integer PowModN(Integer base, int exp, Integer n);
friend bool isprime(Integer a);
friend bool issquare(Integer a);
friend bool testbit(Integer a, unsigned long int bit_number);
friend Integer sqrt(Integer a);
friend int digits(Integer a, int base);
friend int Jacobi(Integer m, Integer n);
friend int Legendre(Integer m, Integer n);
friend Integer random(Integer range);
}; // end 'class Integer'
//
// Misc Number theory functions (non-friendly)
//
Integer lcm(Integer a, Integer b);
Integer LCM(Integer a); // LCM(a) = lcm[1, 2, 3, ..., a]
int logn(Integer a, int base);
int log2(Integer a);
Integer fact(Integer a);
Integer P_n_k(Integer n, Integer k);
Integer C_n_k(Integer n, Integer k);
Integer nextprime(Integer a);
Integer prevprime(Integer a);
Integer SqrtModN(Integer x, Integer p);
#endif // __GMP_INTEGER_CLASS__