#ifndef CLIB_BIGNUM_PROTOS_H
#define CLIB_BIGNUM_PROTOS_H

/*
 *	clib/BigNum_protos.fd
 *
 *	© Allenbrand Brice, Ringard'Production 1996
*/

/********************/
/* Do NOT change !! */
/********************/
#define TMAX 1000

typedef struct
{
 int signe;
 int nc;
 int chiffres[TMAX];
} BigNum,*PtrBigNum;
/********************/
/* Do NOT change !! */
/********************/

#define BigNumSetNul(x) {(x)->chiffres[(x)->nc=0]=0;(x)->signe=1;}
#define BigNumSize(x) ((x)->nc+1)
#define BigNumIsEven(x) (!((x)->chiffres[0]&1))
#define BigNumAbsBigNum(x,y) {BigNumAssign(x,y);x->signe=1;}
#define BigNumIsNul(x) (((!(x)->nc)&&(!(x)->chiffres[0]))?1:0)
#define BigNumIsPositive(x) ((x)->signe)
#define BigNumNegative(x) ((x)->signe=!((x)->signe))

/* Addition */

void BigNumAdd(PtrBigNum x,PtrBigNum y,PtrBigNum z);
void BigNumDigitAdd(PtrBigNum x,int y);

/* Division */

void BigNumDiv(PtrBigNum x,PtrBigNum y,PtrBigNum z);
void BigNumDigitDiv(PtrBigNum x,int y,PtrBigNum z);
void BigNumRightShift(PtrBigNum x,PtrBigNum z);
void BigNumModulo(PtrBigNum x,PtrBigNum y,PtrBigNum z);
void BigNumEDiv(PtrBigNum x,PtrBigNum y,PtrBigNum z,PtrBigNum Rest);

/* Multiplication */

void BigNumMul(PtrBigNum x,PtrBigNum y,PtrBigNum z);
void BigNumDigitMul(PtrBigNum x,int y);
void BigNumLeftShift(PtrBigNum x);

/* Substraction */

void BigNumSub(PtrBigNum x,PtrBigNum y,PtrBigNum z);
void BigNumDigitSub(PtrBigNum x,int y);

/* Displaying */

void BigNumDisplay(PtrBigNum z);
void BigNumPrint(PtrBigNum x);

/* Conversion */

void BigNumStrToBigNum(PtrBigNum x,char *S);
void BigNumToStr(PtrBigNum x,char *y);
void BigNumIntToBigNum(PtrBigNum z,int x);
int BigNumToInt(PtrBigNum z);

/* Comparison */

int BigNumCompare(PtrBigNum x,PtrBigNum y);
int BigNumFastCompare(PtrBigNum x,PtrBigNum y);

/* Prime test */

int BigNumDiffCarre(PtrBigNum n,PtrBigNum res,int lim);
int BigNumRho(PtrBigNum n,PtrBigNum res,int lim);
int BigNumBrutePrime(PtrBigNum i,int aff);

/* Div. */

void BigNumRnd(int n,PtrBigNum z);
void BigNumPgcd(PtrBigNum x,PtrBigNum y,PtrBigNum z);
void BigNumPuiModulo(PtrBigNum x,PtrBigNum y,PtrBigNum z,PtrBigNum t);
int BigNumSqrt(PtrBigNum x,PtrBigNum y);
void BigNumSwap(PtrBigNum x,PtrBigNum y);
void BigNumAssign(PtrBigNum x,PtrBigNum y);

/* Alloc/Free */

PtrBigNum BigNumInit(void);
void BigNumFree(int i);

/* Error codes */

#define DIVIDE_ZERO		1
#define NO_MEMORY 		2
#define TOO_MUCH_BIGNUM 	4
#define TOO_MUCH_FREE_BIGNUM	8
#define INVALID_DOS		16
#define INVALID_GRAPHICS	32
#define INVALID_CPU		64
#define BIGNUM_SIZE_TOO_HIGH	128
#define NEGATIVE_SQRT		256
#define PARTIAL_BIGNUM_TO_INT	512
#define NEGATIVE_PGCD		1024

#define ERROR_TEXT "Warning ! An error %ld occured\n"

#endif /* CLIB_BIGNUM_PROTOS_H */
