diff --git a/GC.c b/GC.c index bde1048..e02e026 100644 --- a/GC.c +++ b/GC.c @@ -1,104 +1,113 @@ #ifndef GC #define GC +#define HAS_BROKENHEART_FLAG(objRef) (((objRef)->size & 1 << (7 * sizeof(unsigned int) -1)) == 0) #include #include #include #include #include "objref.c" #include "instruktion.c" +#include "support.c" -bool halbspeicher1IsActiv = true; -unsigned char* halbspeicher1; -unsigned char* halbspeicher2; -unsigned char* freizeiger; -unsigned int groesse; +ObjRef heap; +ObjRef freePointer; +ObjRef middle; +ObjRef start; +ObjRef end; +ObjRef finalEnd; +ObjRef scanPtr; +ObjRef tmpEnd; -void initHeap(unsigned int size){ - groesse = size*1024/2; - if((halbspeicher1 = malloc(groesse)) == NULL) perror("malloc"); - if((halbspeicher2 = malloc(groesse)) == NULL) perror("malloc"); - freizeiger = halbspeicher1; +unsigned int defaultHeap = 8192 * 1024; + +void heapAlloc(unsigned int size){ + heap = malloc(size); + if(heap == NULL){ + fatalError("Not enough memory on Heap\n"); + } + + start = heap; + freePointer = start; + middle = (heap + (defaultHeap/2)); + end = middle; + finalEnd = (middle + (defaultHeap/2)); } + +void flip(void){ + freePointer = end; + tmpEnd = finalEnd; +} + ObjRef copyObjToFreeMem(ObjRef obj){ - ObjRef copy = (ObjRef) halbspeicher2[freizeiger]; - unsigned int size = (IS_PRIMITIVE(obj))? obj->size : GET_ELEMENT_COUNT(obj)* sizeof(void *); - memcpy((void *) halbspeicher2[freizeiger], obj, size); - freizeiger += size; - return copy; -} -void setBrokenHeart(ObjRef obj, bool val){ - //TODO -} -bool getBrokenHeart(ObjRef obj){ - //TODO - return true; -} -void setForwardPointer(ObjRef obj, void* ref){ - //TODO -} -void *getForwardPointer(ObjRef obj){ - //TODO - return malloc(0); + ObjRef tmp = freePointer; + memcpy(tmp, obj, obj->size); + if(IS_PRIMITIVE(tmp)){ + freePointer += sizeof(tmp) + tmp->size; + }else{ + freePointer += sizeof(tmp) + tmp->size * sizeof(void*); + } + return tmp; } -ObjRef reallocate(ObjRef orig){ +ObjRef rellocate(ObjRef orig){ ObjRef copy; - if(orig == NULL){ - copy == NULL; - }else{ - if(getBrokenHeart(orig)){ - setForwardPointer(copy,orig); - }else{ + if (orig == NULL){ + + copy = NULL; + } else { + unsigned int tmp = HAS_BROKENHEART_FLAG(orig); + if (tmp){ + copy = orig->forward_pointer; + } else { copy = copyObjToFreeMem(orig); - setBrokenHeart(orig,true); - setForwardPointer(orig,copy); + orig->size = (1 | (1 << (7 * sizeof(unsigned int) -1))); + //SET_BROKENHEART_FLAG(orig); + orig->forward_pointer = copy; } } return copy; } -unsigned int getSize(ObjRef obj){ - return (IS_PRIMITIVE(obj))? obj->size : GET_ELEMENT_COUNT(obj)* sizeof(void *); + +void garbageColl(void){ + flip(); + for(int i = 0; i < program_size; i++){ + static_data_area[i] = rellocate(static_data_area[i]); // alte Objekte werden in neue akktive Halbspeicher geleitet bei relocate! + } + bip.op1 = rellocate(bip.op1); + bip.op2 = rellocate(bip.op2); + bip.res = rellocate(bip.res); + bip.rem = rellocate(bip.rem); + returnValueReg = rellocate(returnValueReg); + + scan(); + end = finalEnd; } + +ObjRef garbageCollectorMalloc(unsigned int size){ + if((freePointer + size) > end){ + garbageColl(); + } else if((freePointer > finalEnd)){ + fatalError("Not enough memory on Heap\n"); + } + ObjRef obj = freePointer; + if(obj == NULL){ + fatalError("Object is Null\n"); + } + freePointer += size; + return obj; +} + + void scan(void){ - void *scan = halbspeicher1; - while (scan < freizeiger){ - if(!IS_PRIMITIVE((ObjRef)scan)){ - for (unsigned int i = 0; i < GET_ELEMENT_COUNT((ObjRef)scan); i += getSize(GET_REFS_PTR((ObjRef)scan)[i])) { - GET_REFS_PTR((ObjRef)scan)[i] = reallocate(GET_REFS_PTR((ObjRef)scan)[i]); + scanPtr = start; //Zielspeicherzeiger; + while (scanPtr < freePointer){ + + if (!IS_PRIMITIVE(scanPtr)){ + + for (int i = 0; i < GET_ELEMENT_COUNT(scanPtr); i++){ + GET_REFS_PTR(scanPtr)[i] = rellocate(GET_REFS_PTR(scanPtr)[i]); } } - scan += getSize((ObjRef)scan); - } -} -void *alloc(unsigned int size){ - if((&freizeiger - &halbspeicher1)/8 + size > groesse) { - printf("Heap Overflow\n"); - exit(EXIT_FAILURE); - } - // Set broken heart to false - setBrokenHeart((ObjRef)freizeiger,false); - freizeiger += sizeof(bool) + sizeof(void *); - void *ptr = &freizeiger; - freizeiger += size; - return ptr; -} -void swap(void){ - unsigned char *tmp = halbspeicher1; - halbspeicher1 = halbspeicher2; - halbspeicher2 = tmp; - freizeiger = halbspeicher1; - halbspeicher1IsActiv = !halbspeicher1IsActiv; -} -void triggerGC(void){ - printf("GC triggered\n"); - //TODO -} -void copy(){ - ObjRef *test; - unsigned int objResSize = 2; - if((test = malloc(2*sizeof(test)))==NULL) perror("malloc"); - for (int i = 0; i < objResSize; ++i) { - } } diff --git a/bigint/Makefile b/bigint/Makefile new file mode 100644 index 0000000..0e1dac6 --- /dev/null +++ b/bigint/Makefile @@ -0,0 +1,22 @@ +# +# Makefile for big integer library and test +# + +DIRS = src tst + +all: clean + for i in $(DIRS) ; do \ + $(MAKE) -C $$i install ; \ + done + +clean: + for i in $(DIRS) ; do \ + $(MAKE) -C $$i clean ; \ + done + rm -rf ./build + rm -f *~ + +dist: clean + (cd .. ; \ + tar -cvf bigint.tar bigint ; \ + gzip -f bigint.tar) diff --git a/bigint/README b/bigint/README new file mode 100644 index 0000000..0f0534d --- /dev/null +++ b/bigint/README @@ -0,0 +1,92 @@ +The "bigint" Package +==================== + +1. What is it? +-------------- + +This package implements a multiple-precision integer arithmetic package, +i.e., a collection of functions which can calculate with integers having +arbitrarily many digits. The algorithms are taken from [D. Knuth: The +Art of Computer Programming, Vol. 2, Seminumerical Algorithms], the +implementation language is C. + + +2. "Multiple Precision" - how does it work? +------------------------------------------- + +Each integer number is represented as an array of digits. The array +is large enough to hold the number of digits necessary to represent +the number. Each digit occupies a single byte, so the number base of +this representation is 256. Addition, subtraction, and multiplication +work as we all have learned it: perform the desired operation digit +by digit, starting from the least significant digit, and observing +any "carries" from one place to the next higher one. Division is a +little bit more complicated because there is a certain amount of +guesswork involved. Knuth gives a formal treatment of this guesswork. + + +3. How do I use it? +------------------- + +Because every big integer may have a differently sized array to hold +its digits, these structures are dynamically allocated on the heap of +the C runtime system, and accessed by pointers. If you want to perform +an arithmetic operation on one or two big integers, you have to load +the corresponding pointers into a structure called BIP ("Big Integer +Processor"), and call the arithmetic function. When the function has +returned, the pointer to the result of the operation can be found in +another component of the BIP. The following functions are available: + + int bigSgn(void); /* sign */ + int bigCmp(void); /* comparison */ + void bigNeg(void); /* negation */ + void bigAdd(void); /* addition */ + void bigSub(void); /* subtraction */ + void bigMul(void); /* multiplication */ + void bigDiv(void); /* division */ + void bigFromInt(int n); /* conversion int --> big */ + int bigToInt(void); /* conversion big --> int */ + void bigRead(FILE *in); /* read a big integer */ + void bigPrint(FILE *out); /* print a big integer */ + void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer */ + +Some of these functions accept or return ordinary integers. For the +exact definition of each function's interface, please see the comments +in the function's source. + + +4. What else is needed? +----------------------- + +The library tries to detect fatal errors in using its functions (e.g., +null pointers to operands) as well as internal errors (which "cannot +happen"). In either case a user-supplied error routine is called, which +is supposed to print an error message and then to terminate the program. + +The library does not attempt to manage memory. For this purpose, it +relies on a user-supplied function "void* newPrimObject(int dataSize)", +which should allocate sufficiently many bytes and return a pointer to +a created object. In addition, the library needs to access a data field +- that implements the size-as-needed cocept - within the created object, +to actualy manage the data structures that represent the values of the +integer number. For this, the following function can be used: + +void * getPrimObjectDataPointer(void * obj){ + ObjRef oo = ((ObjRef) (obj)); + return oo->data; +} + +This function must also be a user-supplied function that must be +implemented by the program that wants to use this library. + +For details about these three user-supplied functions take a look in +the file "support.c" in the directory "tst". + + +5. What is in the directory "tst"? +---------------------------------- + +Well, you may have guessed it already: these are test cases for the +library. You can learn how to link against the library by inspecting +the "Makefile" for the tests, and you can find a simple implementation +of the support library. diff --git a/bigint/build/bin/testbip b/bigint/build/bin/testbip new file mode 100755 index 0000000..02f1195 Binary files /dev/null and b/bigint/build/bin/testbip differ diff --git a/bigint/build/include/bigint.h b/bigint/build/include/bigint.h new file mode 100644 index 0000000..b93d88e --- /dev/null +++ b/bigint/build/include/bigint.h @@ -0,0 +1,60 @@ +/* + * bigint.h -- big integer library + */ + + +#ifndef _BIGINT_H_ +#define _BIGINT_H_ + + +/* object representation */ +typedef void* BigObjRef; + + +#include + + +typedef struct { + int nd; /* number of digits; array may be bigger */ + /* nd = 0 exactly when number = 0 */ + unsigned char sign; /* one of BIG_NEGATIVE or BIG_POSITIVE */ + /* zero always has BIG_POSITIVE here */ + unsigned char digits[1]; /* the digits proper; number base is 256 */ + /* LS digit first; MS digit is not zero */ +} Big; + +#include "support.h" + + +/* big integer processor registers */ + +typedef struct { + BigObjRef op1; /* first (or single) operand */ + BigObjRef op2; /* second operand (if present) */ + BigObjRef res; /* result of operation */ + BigObjRef rem; /* remainder in case of division */ +} BIP; + +extern BIP bip; /* registers of the processor */ + + +/* big integer processor functions */ + +int bigSgn(void); /* sign */ +int bigCmp(void); /* comparison */ +void bigNeg(void); /* negation */ +void bigAdd(void); /* addition */ +void bigSub(void); /* subtraction */ +void bigMul(void); /* multiplication */ +void bigDiv(void); /* division */ + +void bigFromInt(int n); /* conversion int --> big */ +int bigToInt(void); /* conversion big --> int */ + +void bigRead(FILE *in); /* read a big integer */ +void bigPrint(FILE *out); /* print a big integer */ + +void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer object */ + + +#endif /* _BIGINT_H_ */ diff --git a/bigint/build/include/support.h b/bigint/build/include/support.h new file mode 100644 index 0000000..8e4455e --- /dev/null +++ b/bigint/build/include/support.h @@ -0,0 +1,15 @@ +/* + * support.h -- object representation and support functions + */ + + +#ifndef _SUPPORT_H_ +#define _SUPPORT_H_ + +/* support functions */ + +void fatalError(char *msg); /* print a message and exit */ +void * newPrimObject(int dataSize); /* create a new primitive object */ +void * getPrimObjectDataPointer(void * primObject); + +#endif /* _SUPPORT_H_ */ diff --git a/bigint/build/lib/libbigint.a b/bigint/build/lib/libbigint.a new file mode 100644 index 0000000..01ff579 Binary files /dev/null and b/bigint/build/lib/libbigint.a differ diff --git a/bigint/src/Makefile b/bigint/src/Makefile new file mode 100644 index 0000000..6973380 --- /dev/null +++ b/bigint/src/Makefile @@ -0,0 +1,26 @@ +# +# Makefile for big integer library +# + +BUILD = ../build + +CC = gcc +CFLAGS = -g -Wall + +all: support.h bigint.h libbigint.a + +install: all + mkdir -p $(BUILD)/include + cp support.h $(BUILD)/include + cp bigint.h $(BUILD)/include + mkdir -p $(BUILD)/lib + cp libbigint.a $(BUILD)/lib + +libbigint.a: bigint.o + ar -crs libbigint.a bigint.o + +bigint.o: bigint.c bigint.h support.h + $(CC) $(CFLAGS) -o bigint.o -c bigint.c + +clean: + rm -f *~ bigint.o libbigint.a diff --git a/bigint/src/bigint.c b/bigint/src/bigint.c new file mode 100644 index 0000000..90aa5ab --- /dev/null +++ b/bigint/src/bigint.c @@ -0,0 +1,987 @@ +/* + * bigint.c -- big integer library + */ + + +#include +#include + +#include "bigint.h" + +/**************************************************************/ + +/* debugging */ + + +#define DIV_CHK_01 0 +#define DIV_CHK_02 0 +#define DIV_CHK_03 0 +#define DIV_CHK_04 0 +#define DIV_CHK_05 0 +#define DIV_CHK_06 0 +#define DIV_CHK_07 0 +#define DIV_CHK_08 0 +#define DIV_CHK_09 0 +#define DIV_CHK_10 0 +#define DIV_CHK_11 0 + + +/**************************************************************/ + +/* big integer representation */ + + +#define BIG_NEGATIVE ((unsigned char) 0) +#define BIG_POSITIVE ((unsigned char) 1) + + +#define BIG_PTR(bigObjRef) ((Big *) (getPrimObjectDataPointer(bigObjRef))) +#define GET_ND(bigObjRef) (BIG_PTR(bigObjRef)->nd) +#define SET_ND(bigObjRef, val) (BIG_PTR(bigObjRef)->nd = (val)) +#define GET_SIGN(bigObjRef) (BIG_PTR(bigObjRef)->sign) +#define SET_SIGN(bigObjRef, val) (BIG_PTR(bigObjRef)->sign = (val)) +#define GET_DIGIT(bigObjRef, i) (BIG_PTR(bigObjRef)->digits[i]) +#define SET_DIGIT(bigObjRef, i, val) (BIG_PTR(bigObjRef)->digits[i] = (val)) + + +/**************************************************************/ + +/* global data */ + + +/* + * registers of the big integer processor + */ +BIP bip = { + NULL, /* op1 */ + NULL, /* op2 */ + NULL, /* res */ + NULL, /* rem */ +}; + + +/**************************************************************/ + + +/* + * construct a new big integer object + * + * number of digits is given by parameter + * a reference to a proper object is returned + * but no component of the big integer is set + * + * ATTENTION: All object references stored in + * places other than the bip registers may become + * invalid as soon as this function is called! + */ +static BigObjRef newBig(int nd) { + int dataSize; + BigObjRef bigObjRef; + + dataSize = sizeof(int) + 1 + nd; + bigObjRef = newPrimObject(dataSize); + return bigObjRef; +} + + +/**************************************************************/ + +/* big integer unsigned arithmetic */ + + +/* + * exchange bip.op1 and bip.op2 + */ +static void bigXchg(void) { + BigObjRef tmp; + + tmp = bip.op1; + bip.op1 = bip.op2; + bip.op2 = tmp; +} + + +/* + * big integer unsigned comparison + * + * operands in bip.op1 and bip.op2 + * result is < 0, = 0, or > 0 if and only if the + * same relation holds for bip.op1 and bip.op2 + */ +static int bigUcmp(void) { + int nd1; + int nd2; + int diff; + + /* compare sizes */ + nd1 = GET_ND(bip.op1); + nd2 = GET_ND(bip.op2); + if (nd1 != nd2) { + /* sizes are different: we know the bigger number */ + return nd1 - nd2; + } + /* sizes are equal: we must look at the digits */ + while (nd1--) { + diff = (int) GET_DIGIT(bip.op1, nd1) - + (int) GET_DIGIT(bip.op2, nd1); + if (diff != 0) { + return diff; + } + } + /* the numbers are equal */ + return 0; +} + + +/* + * big integer unsigned addition + * + * operands in bip.op1 and bip.op2 + * result in bip.res + */ +static void bigUadd(void) { + int nd1; + int nd2; + int i; + unsigned short carry; + unsigned short aux; + int xchgFlag; + + /* make sure op1 has at least as many digits as op2 */ + nd1 = GET_ND(bip.op1); + nd2 = GET_ND(bip.op2); + if (nd1 < nd2) { + /* exchange operands */ + bigXchg(); + i = nd1; + nd1 = nd2; + nd2 = i; + xchgFlag = 1; + } else { + /* don't exchange operands */ + xchgFlag = 0; + } + /* allocate result */ + bip.res = newBig(nd1 + 1); + /* copy op2 to result */ + for (i = 0; i < nd2; i++) { + SET_DIGIT(bip.res, i, GET_DIGIT(bip.op2, i)); + } + /* fill result with 0 up to size of op1 */ + for (; i < nd1; i++) { + SET_DIGIT(bip.res, i, 0); + } + /* res = op1 + res */ + carry = 0x00; + for (i = 0; i < nd1; i++) { + aux = (unsigned short) GET_DIGIT(bip.op1, i) + + (unsigned short) GET_DIGIT(bip.res, i) + + carry; + SET_DIGIT(bip.res, i, aux & 0xFF); + carry = aux >> 8; + } + SET_DIGIT(bip.res, i, carry); + /* determine actual size of result */ + i = nd1 + 1; + while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ; + SET_ND(bip.res, i + 1); + /* restore operands */ + if (xchgFlag) { + bigXchg(); + } +} + + +/* + * big integer unsigned subtraction + * + * operands in bip.op1 and bip.op2 + * result in bip.res, must not be negative + */ +static void bigUsub(void) { + int nd1; + int nd2; + int i; + unsigned short carry; + unsigned short aux; + + /* op1 must have at least as many digits as op2 */ + nd1 = GET_ND(bip.op1); + nd2 = GET_ND(bip.op2); + if (nd1 < nd2) { + /* unsigned subtraction would yield negative result */ + fatalError("internal library error #1 - THIS SHOULD NEVER HAPPEN!"); + } + /* allocate result */ + bip.res = newBig(nd1); + /* copy op2 to result */ + for (i = 0; i < nd2; i++) { + SET_DIGIT(bip.res, i, GET_DIGIT(bip.op2, i)); + } + /* fill result with 0 up to size of op1 */ + for (; i < nd1; i++) { + SET_DIGIT(bip.res, i, 0); + } + /* res = op1 - res */ + carry = 0x01; + for (i = 0; i < nd1; i++) { + aux = (unsigned short) GET_DIGIT(bip.op1, i) - + (unsigned short) GET_DIGIT(bip.res, i) + + carry + 0xFF; + SET_DIGIT(bip.res, i, aux & 0xFF); + carry = aux >> 8; + } + if (carry != 0x01) { + /* unsigned subtraction would yield negative result */ + fatalError("internal library error #2 - THIS SHOULD NEVER HAPPEN!"); + } + /* determine actual size of result */ + i = nd1; + while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ; + SET_ND(bip.res, i + 1); +} + + +/* + * big integer unsigned multiplication + * + * operands in bip.op1 and bip.op2 + * result in bip.res + */ +static void bigUmul(void) { + int nd1; + int nd2; + int i, j, k; + unsigned short carry; + unsigned short aux; + + /* get sizes of operands */ + nd1 = GET_ND(bip.op1); + nd2 = GET_ND(bip.op2); + /* allocate result */ + bip.res = newBig(nd1 + nd2); + /* reset lower nd1 digits of result */ + for (i = 0; i < nd1; i++) { + SET_DIGIT(bip.res, i, 0); + } + /* res = op1 * op2 */ + for (j = 0; j < nd2; j++) { + carry = 0x00; + for (k = j, i = 0; i < nd1; k++, i++) { + aux = (unsigned short) GET_DIGIT(bip.op1, i) * + (unsigned short) GET_DIGIT(bip.op2, j) + + (unsigned short) GET_DIGIT(bip.res, k) + + carry; + SET_DIGIT(bip.res, k, aux & 0xFF); + carry = aux >> 8; + } + SET_DIGIT(bip.res, k, carry); + } + /* determine actual size of result */ + i = nd1 + nd2; + while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ; + SET_ND(bip.res, i + 1); +} + + +/* + * big integer unsigned division by single digit divisor + * + * dividend in bip.rem, divisor in parameter + * quotient in bip.rem, remainder is returned + */ +static unsigned char bigUdiv1(unsigned char divisor) { + BigObjRef tmp; + int nd; + int i; + unsigned short d, r; + unsigned short aux; + + /* get size of dividend */ + nd = GET_ND(bip.rem); + /* check for division by zero */ + d = (unsigned short) divisor; + if (d == 0) { + fatalError("internal library error #3 - THIS SHOULD NEVER HAPPEN!"); + } + /* allocate result */ + tmp = newBig(nd); + /* tmp = dividend / divisor, r = dividend % divisor */ + r = 0; + for (i = nd - 1; i >= 0; i--) { + aux = (r << 8) | (unsigned short) GET_DIGIT(bip.rem, i); + SET_DIGIT(tmp, i, aux / d); + r = aux % d; + } + /* determine actual size of quotient */ + i = nd; + while (--i >= 0 && GET_DIGIT(tmp, i) == 0) ; + SET_ND(tmp, i + 1); + /* store quotient */ + bip.rem = tmp; + /* return remainder */ + return (unsigned char) r; +} + + +/* + * big integer unsigned division + * + * dividend in bip.op1, divisor in bip.op2 + * quotient in bip.res, remainder in bip.rem + */ +static void bigUdiv(void) { + BigObjRef tmp; + int nd1; + int nd2; + int nd3; + int i, j, k, l; + unsigned char r; + unsigned short scale; + unsigned short carry; + unsigned short aux; + unsigned short qhat; + unsigned short v1, v2; + unsigned short uj0, uj1, uj2, two; + + /* get sizes of operands */ + nd1 = GET_ND(bip.op1); + nd2 = GET_ND(bip.op2); + /* check for division by zero */ + if (nd2 == 0) { + fatalError("division by zero"); + } + /* check for small dividend */ + if (bigUcmp() < 0) { + /* res = 0 */ + bip.res = newBig(0); + SET_ND(bip.res, 0); + /* rem = op1; BUT THIS HAS TO BE A COPY! */ + bip.rem = newBig(nd1); + for (i = 0; i < nd1; i++) { + SET_DIGIT(bip.rem, i, GET_DIGIT(bip.op1, i)); + } + SET_ND(bip.rem, nd1); + return; + } + /* check for single digit divisor */ + if (nd2 == 1) { + /* yes - use simple division by single digit divisor */ + bip.rem = bip.op1; + r = bigUdiv1(GET_DIGIT(bip.op2, 0)); + bip.res = bip.rem; + if (r == 0) { + bip.rem = newBig(0); + SET_ND(bip.rem, 0); + } else { + bip.rem = newBig(1); + SET_ND(bip.rem, 1); + SET_DIGIT(bip.rem, 0, r); + } + return; + } + /* + * now for the general case + */ +#if DIV_CHK_01 + printf("div_chk #01: division, general case\n"); + printf(" dividend = "); + bigDump(stdout, bip.op1); + printf("\n"); + printf(" divisor = "); + bigDump(stdout, bip.op2); + printf("\n"); +#endif + /* determine scale factor for normalization */ + scale = (unsigned short) 256 / + ((unsigned short) GET_DIGIT(bip.op2, nd2 - 1) + 1); +#if DIV_CHK_02 + printf("div_chk #02: scale factor = %02X\n", scale); +#endif + /* normalize dividend, result is in bip.rem */ + bip.rem = newBig(nd1 + 1); + carry = 0x00; + for (i = 0; i < nd1; i++) { + aux = (unsigned short) GET_DIGIT(bip.op1, i) * scale + + carry; + SET_DIGIT(bip.rem, i, aux & 0xFF); + carry = aux >> 8; + } + SET_DIGIT(bip.rem, i, carry); + SET_ND(bip.rem, nd1 + 1); +#if DIV_CHK_03 + printf("div_chk #03: normalized dividend = "); + bigDump(stdout, bip.rem); + printf("\n"); +#endif + /* normalize divisor, result is in bip.res */ + bip.res = newBig(nd2); + carry = 0x00; + for (i = 0; i < nd2; i++) { + aux = (unsigned short) GET_DIGIT(bip.op2, i) * scale + + carry; + SET_DIGIT(bip.res, i, aux & 0xFF); + carry = aux >> 8; + } + if (carry != 0x00) { + /* overflow in divisor normalization */ + fatalError("internal library error #4 - THIS SHOULD NEVER HAPPEN!"); + } + SET_ND(bip.res, nd2); +#if DIV_CHK_04 + printf("div_chk #04: normalized divisor = "); + bigDump(stdout, bip.res); + printf("\n"); +#endif + /* allocate quotient */ + nd3 = nd1 - nd2 + 1; + tmp = newBig(nd3); + /* extract the two most significand digits of divisor */ + v1 = (unsigned short) GET_DIGIT(bip.res, nd2 - 1); + v2 = (unsigned short) GET_DIGIT(bip.res, nd2 - 2); + /* loop on digits of dividend and compute digits of quotient */ + /* j is index into dividend, k is index into quotient */ + for (j = nd1, k = nd3 - 1; k >= 0; j--, k--) { +#if DIV_CHK_05 + printf("div_chk #05: j = %d, k = %d\n", j, k); +#endif + /* calculate qhat */ + uj0 = (unsigned short) GET_DIGIT(bip.rem, j); + uj1 = (unsigned short) GET_DIGIT(bip.rem, j - 1); + uj2 = (unsigned short) GET_DIGIT(bip.rem, j - 2); + two = (uj0 << 8) | uj1; + if (uj0 == v1) { + qhat = (unsigned short) 255; +#if DIV_CHK_06 + printf("div_chk #06a: qhat = %02X\n", qhat); +#endif + } else { + qhat = two / v1; +#if DIV_CHK_06 + printf("div_chk #06b: qhat = %02X\n", qhat); +#endif + } + while (qhat * v2 > (((two - qhat * v1) << 8) | uj2)) { + qhat--; +#if DIV_CHK_07 + printf("div_chk #07: qhat decremented, is now %02X\n", qhat); +#endif + } + /* multiply and subtract */ + /* l is index into dividend, i is index into divisor */ + carry = 0xFF; + for (l = j - nd2, i = 0; i < nd2; l++, i++) { + aux = (unsigned short) GET_DIGIT(bip.rem, l) - + (unsigned short) GET_DIGIT(bip.res, i) * qhat + + carry + 0xFE01; + SET_DIGIT(bip.rem, l, aux & 0xFF); + carry = aux >> 8; + } + aux = (unsigned short) GET_DIGIT(bip.rem, l) + + carry + 0xFE01; + SET_DIGIT(bip.rem, l, aux & 0xFF); + carry = aux >> 8; +#if DIV_CHK_08 + printf("div_chk #08: remainder = "); + bigDump(stdout, bip.rem); + printf("\n"); +#endif + /* test remainder and possibly add back */ + if (carry != 0xFF) { + /* qhat is one too large */ + qhat--; +#if DIV_CHK_09 + printf("div_chk #09: qhat final correction, is now %02X\n", qhat); +#endif + /* add back */ + /* l is index into dividend, i is index into divisor */ + carry = 0x00; + for (l = j - nd2, i = 0; i < nd2; l++, i++) { + aux = (unsigned short) GET_DIGIT(bip.rem, l) + + (unsigned short) GET_DIGIT(bip.res, i) + + carry; + SET_DIGIT(bip.rem, l, aux & 0xFF); + carry = aux >> 8; + } + aux = (unsigned short) GET_DIGIT(bip.rem, l) + + carry; + SET_DIGIT(bip.rem, l, aux & 0xFF); + carry = aux >> 8; + if (carry != 0x01) { + /* missing carry in add-back sum */ + fatalError("internal library error #5 - THIS SHOULD NEVER HAPPEN!"); + } +#if DIV_CHK_10 + printf("div_chk #10: remainder = "); + bigDump(stdout, bip.rem); + printf("\n"); +#endif + } + /* store quotient digit */ + SET_DIGIT(tmp, k, qhat); +#if DIV_CHK_11 + printf("div_chk #11: quotient digit = %02X\n", qhat); +#endif + } + /* finish quotient */ + i = nd3; + while (--i >= 0 && GET_DIGIT(tmp, i) == 0) ; + SET_ND(tmp, i + 1); + bip.res = tmp; + /* finish and unnormalize remainder */ + i = nd1 + 1; + while (--i >= 0 && GET_DIGIT(bip.rem, i) == 0) ; + SET_ND(bip.rem, i + 1); + r = bigUdiv1(scale); + if (r != 0) { + /* non-zero remainder in unnormalization */ + fatalError("internal library error #6 - THIS SHOULD NEVER HAPPEN!"); + } +} + + +/**************************************************************/ + +/* nil reference exception */ + + +static void nilRefException(void) { + fatalError("big integer library detected illegal nil reference"); +} + + +/**************************************************************/ + +/* big integer arithmetic */ + + +/* + * big integer sign + * + * operand in bip.op1 + * result is < 0, = 0, or > 0 if and only if + * the same relation holds for bip.op1 + */ +int bigSgn(void) { + if (bip.op1 == NULL) { + nilRefException(); + } + if (GET_ND(bip.op1) == 0) { + return 0; + } + if (GET_SIGN(bip.op1) == BIG_POSITIVE) { + return 1; + } else { + return -1; + } +} + + +/* + * big integer comparison + * + * operands in bip.op1 and bip.op2 + * result is < 0, = 0, or > 0 if and only if the + * same relation holds for bip.op1 and bip.op2 + */ +int bigCmp(void) { + if (bip.op1 == NULL || + bip.op2 == NULL) { + nilRefException(); + } + if (GET_SIGN(bip.op1) == BIG_POSITIVE) { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 >= 0 and op2 >= 0 */ + return bigUcmp(); + } else { + /* op1 >= 0 and op2 < 0 */ + return 1; + } + } else { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 < 0 and op2 >= 0 */ + return -1; + } else { + /* op1 < 0 and op2 < 0 */ + return -bigUcmp(); + } + } +} + + +/* + * big integer negation + * + * operand in bip.op1 + * result in bip.res + */ +void bigNeg(void) { + int nd; + int i; + + if (bip.op1 == NULL) { + nilRefException(); + } + /* make copy of operand */ + nd = GET_ND(bip.op1); + bip.res = newBig(nd); + for (i = 0; i < nd; i++) { + SET_DIGIT(bip.res, i, GET_DIGIT(bip.op1, i)); + } + SET_ND(bip.res, nd); + /* store inverted sign */ + if (GET_SIGN(bip.op1) == BIG_NEGATIVE || nd == 0) { + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + SET_SIGN(bip.res, BIG_NEGATIVE); + } +} + + +/* + * big integer addition + * + * operands in bip.op1 and bip.op2 + * result in bip.res + */ +void bigAdd(void) { + if (bip.op1 == NULL || + bip.op2 == NULL) { + nilRefException(); + } + if (GET_SIGN(bip.op1) == BIG_POSITIVE) { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 >= 0 and op2 >= 0 */ + bigUadd(); + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + /* op1 >= 0 and op2 < 0 */ + if (bigUcmp() >= 0) { + /* |op1| >= |op2| */ + bigUsub(); + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + /* |op1| < |op2| */ + bigXchg(); + bigUsub(); + SET_SIGN(bip.res, BIG_NEGATIVE); + bigXchg(); + } + } + } else { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 < 0 and op2 >= 0 */ + if (bigUcmp() <= 0) { + /* |op1| <= |op2| */ + bigXchg(); + bigUsub(); + SET_SIGN(bip.res, BIG_POSITIVE); + bigXchg(); + } else { + /* |op1| > |op2| */ + bigUsub(); + SET_SIGN(bip.res, BIG_NEGATIVE); + } + } else { + /* op1 < 0 and op2 < 0 */ + bigUadd(); + SET_SIGN(bip.res, BIG_NEGATIVE); + } + } +} + + +/* + * big integer subtraction + * + * operands in bip.op1 and bip.op2 + * result in bip.res + */ +void bigSub(void) { + if (bip.op1 == NULL || + bip.op2 == NULL) { + nilRefException(); + } + if (GET_SIGN(bip.op1) == BIG_POSITIVE) { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 >= 0 and op2 >= 0 */ + if (bigUcmp() >= 0) { + /* |op1| >= |op2| */ + bigUsub(); + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + /* |op1| < |op2| */ + bigXchg(); + bigUsub(); + SET_SIGN(bip.res, BIG_NEGATIVE); + bigXchg(); + } + } else { + /* op1 >= 0 and op2 < 0 */ + bigUadd(); + SET_SIGN(bip.res, BIG_POSITIVE); + } + } else { + if (GET_SIGN(bip.op2) == BIG_POSITIVE) { + /* op1 < 0 and op2 >= 0 */ + bigUadd(); + SET_SIGN(bip.res, BIG_NEGATIVE); + } else { + /* op1 < 0 and op2 < 0 */ + if (bigUcmp() <= 0) { + /* |op1| <= |op2| */ + bigXchg(); + bigUsub(); + SET_SIGN(bip.res, BIG_POSITIVE); + bigXchg(); + } else { + /* |op1| > |op2| */ + bigUsub(); + SET_SIGN(bip.res, BIG_NEGATIVE); + } + } + } +} + + +/* + * big integer multiplication + * + * operands in bip.op1 and bip.op2 + * result in bip.res + */ +void bigMul(void) { + if (bip.op1 == NULL || + bip.op2 == NULL) { + nilRefException(); + } + bigUmul(); + if (GET_SIGN(bip.op1) == GET_SIGN(bip.op2) || GET_ND(bip.res) == 0) { + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + SET_SIGN(bip.res, BIG_NEGATIVE); + } +} + + +/* + * big integer division, truncating towards zero + * + * dividend in bip.op1, divisor in bip.op2 + * quotient in bip.res, remainder in bip.rem + */ +void bigDiv(void) { + if (bip.op1 == NULL || + bip.op2 == NULL) { + nilRefException(); + } + bigUdiv(); + if (GET_SIGN(bip.op1) == GET_SIGN(bip.op2) || GET_ND(bip.res) == 0) { + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + SET_SIGN(bip.res, BIG_NEGATIVE); + } + if (GET_SIGN(bip.op1) == BIG_POSITIVE || GET_ND(bip.rem) == 0) { + SET_SIGN(bip.rem, BIG_POSITIVE); + } else { + SET_SIGN(bip.rem, BIG_NEGATIVE); + } +} + + +/**************************************************************/ + +/* big integer conversions */ + + +/* + * conversion int --> big + * + * operand in parameter + * result in bip.res + */ +void bigFromInt(int n) { + int i; + + bip.res = newBig(sizeof(int)); + if (n < 0) { + n = -n; + SET_SIGN(bip.res, BIG_NEGATIVE); + } else { + SET_SIGN(bip.res, BIG_POSITIVE); + } + for (i = 0; i < sizeof(int); i++) { + SET_DIGIT(bip.res, i, n & 0xFF); + n >>= 8; + } + while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ; + SET_ND(bip.res, i + 1); +} + + +/* + * conversion big --> int + * + * operand in bip.op1 + * result is returned + */ +int bigToInt(void) { + int nd; + int i; + int res; + + if (bip.op1 == NULL) { + nilRefException(); + } + nd = GET_ND(bip.op1); + if (nd > 4 || + (nd == 4 && GET_DIGIT(bip.op1, 3) >= 0x80)) { + fatalError("big integer too big for conversion to int"); + } + res = 0; + for (i = nd - 1; i >= 0; i--) { + res <<= 8; + res |= (unsigned int) GET_DIGIT(bip.op1, i); + } + if (GET_SIGN(bip.op1) == BIG_NEGATIVE) { + res = -res; + } + return res; +} + + +/**************************************************************/ + +/* big integer I/O */ + + +/* + * read a big integer + * + * stream to read from in parameter + * result in bip.res + */ +void bigRead(FILE *in) { + int c; + int positive; + + c = fgetc(in); + while (isspace(c)) { + c = fgetc(in); + } + if (c == '-') { + positive = 0; + c = fgetc(in); + } else { + positive = 1; + if (c == '+') { + c = fgetc(in); + } + } + if (!isdigit(c)) { + fatalError("no digits in input"); + } + bigFromInt(10); + bip.rem = bip.res; + bigFromInt(0); + while (isdigit(c)) { + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigUmul(); + bip.op1 = bip.res; + bigFromInt(c - '0'); + bip.op2 = bip.res; + bigUadd(); + c = fgetc(in); + } + ungetc(c, in); + if (positive || GET_ND(bip.res) == 0) { + SET_SIGN(bip.res, BIG_POSITIVE); + } else { + SET_SIGN(bip.res, BIG_NEGATIVE); + } +} + + +/* + * print a big integer + * + * stream to write to in parameter + * number to print in bip.op1 + */ +void bigPrint(FILE *out) { + int nd; + unsigned char r; + int skipZero; + + if (bip.op1 == NULL) { + nilRefException(); + } + nd = GET_ND(bip.op1); + if (nd == 0) { + fprintf(out, "0"); + return; + } + if (GET_SIGN(bip.op1) == BIG_NEGATIVE) { + fprintf(out, "-"); + } + /* number of digits in base 10 = number of digits + in base 256 * log10(256), and log10(256) < 2.5 */ + nd = 2 * nd + nd / 2; + bip.rem = bip.op1; + bigFromInt(10); + bip.op2 = bip.res; + bigFromInt(1); + while (nd != 0) { + bip.op1 = bip.res; + bigUmul(); + nd--; + } + bip.op1 = bip.rem; + bip.op2 = bip.res; + skipZero = 1; + do { + bigUdiv(); + if (GET_ND(bip.res) == 0) { + if (!skipZero) { + fprintf(out, "0"); + } + } else { + if (GET_ND(bip.res) != 1) { + fatalError("internal library error #7 - THIS SHOULD NEVER HAPPEN!"); + } + fprintf(out, "%c", GET_DIGIT(bip.res, 0) + '0'); + skipZero = 0; + } + bip.op1 = bip.rem; + bip.rem = bip.op2; + r = bigUdiv1(10); + bip.op2 = bip.rem; + } while (r == 0); +} + + +/**************************************************************/ + +/* debugging */ + + +/* + * dump a big integer object + */ +void bigDump(FILE *out, BigObjRef bigObjRef) { + int nd; + unsigned char sign; + int i; + + if (bigObjRef == NULL) { + nilRefException(); + } + nd = GET_ND(bigObjRef); + sign = GET_SIGN(bigObjRef); + fprintf(out, "[%d %c", nd, sign == BIG_POSITIVE ? '+' : '-'); + for (i = 0; i < nd; i++) { + fprintf(out, " %02X", GET_DIGIT(bigObjRef, i)); + } + fprintf(out, "]"); +} diff --git a/bigint/src/bigint.h b/bigint/src/bigint.h new file mode 100644 index 0000000..b93d88e --- /dev/null +++ b/bigint/src/bigint.h @@ -0,0 +1,60 @@ +/* + * bigint.h -- big integer library + */ + + +#ifndef _BIGINT_H_ +#define _BIGINT_H_ + + +/* object representation */ +typedef void* BigObjRef; + + +#include + + +typedef struct { + int nd; /* number of digits; array may be bigger */ + /* nd = 0 exactly when number = 0 */ + unsigned char sign; /* one of BIG_NEGATIVE or BIG_POSITIVE */ + /* zero always has BIG_POSITIVE here */ + unsigned char digits[1]; /* the digits proper; number base is 256 */ + /* LS digit first; MS digit is not zero */ +} Big; + +#include "support.h" + + +/* big integer processor registers */ + +typedef struct { + BigObjRef op1; /* first (or single) operand */ + BigObjRef op2; /* second operand (if present) */ + BigObjRef res; /* result of operation */ + BigObjRef rem; /* remainder in case of division */ +} BIP; + +extern BIP bip; /* registers of the processor */ + + +/* big integer processor functions */ + +int bigSgn(void); /* sign */ +int bigCmp(void); /* comparison */ +void bigNeg(void); /* negation */ +void bigAdd(void); /* addition */ +void bigSub(void); /* subtraction */ +void bigMul(void); /* multiplication */ +void bigDiv(void); /* division */ + +void bigFromInt(int n); /* conversion int --> big */ +int bigToInt(void); /* conversion big --> int */ + +void bigRead(FILE *in); /* read a big integer */ +void bigPrint(FILE *out); /* print a big integer */ + +void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer object */ + + +#endif /* _BIGINT_H_ */ diff --git a/bigint/src/bigint.o b/bigint/src/bigint.o new file mode 100644 index 0000000..4e68f95 Binary files /dev/null and b/bigint/src/bigint.o differ diff --git a/bigint/src/libbigint.a b/bigint/src/libbigint.a new file mode 100644 index 0000000..01ff579 Binary files /dev/null and b/bigint/src/libbigint.a differ diff --git a/bigint/src/support.h b/bigint/src/support.h new file mode 100644 index 0000000..8e4455e --- /dev/null +++ b/bigint/src/support.h @@ -0,0 +1,15 @@ +/* + * support.h -- object representation and support functions + */ + + +#ifndef _SUPPORT_H_ +#define _SUPPORT_H_ + +/* support functions */ + +void fatalError(char *msg); /* print a message and exit */ +void * newPrimObject(int dataSize); /* create a new primitive object */ +void * getPrimObjectDataPointer(void * primObject); + +#endif /* _SUPPORT_H_ */ diff --git a/bigint/tst/Makefile b/bigint/tst/Makefile new file mode 100644 index 0000000..67ca0eb --- /dev/null +++ b/bigint/tst/Makefile @@ -0,0 +1,28 @@ +# +# Makefile for big integer test +# + +BUILD = ../build + +CC = gcc +CFLAGS = -g -Wall -I$(BUILD)/include +LDFLAGS = -g -Wall -L$(BUILD)/lib +LDLIBS = -lbigint + +all: testbip + +install: all + mkdir -p $(BUILD)/bin + cp testbip $(BUILD)/bin + +testbip: testbip.o support.o + $(CC) $(LDFLAGS) -o testbip testbip.o support.o $(LDLIBS) + +testbip.o: testbip.c + $(CC) $(CFLAGS) -o testbip.o -c testbip.c + +support.o: support.c + $(CC) $(CFLAGS) -o support.o -c support.c + +clean: + rm -f *~ testbip.o support.o testbip diff --git a/bigint/tst/support.c b/bigint/tst/support.c new file mode 100644 index 0000000..f8ae80d --- /dev/null +++ b/bigint/tst/support.c @@ -0,0 +1,58 @@ +/* + * support.c -- support functions for big integer library + */ + + +#include +#include +#include + +#include "support.h" + +typedef struct ObjRef{ + bool brokenHeart; + struct ObjRef *forward_pointer; + unsigned int size; + unsigned char data[1]; +} *ObjRef; + + +/* + * This routine is called in case a fatal error has occurred. + * It should print the error message and terminate the program. + */ +void fatalError(char *msg) { + printf("Fatal error: %s\n", msg); + exit(1); +} + + +/* + * This function is called whenever a new primitive object with + * a certain amount of internal memory is needed. It should return + * an object reference to a regular object, which contains a freely + * usable memory area of at least the requested size (measured in + * bytes). The memory area need not be initialized in any way. + * + * Note that this function may move all objects in memory at will + * (due to, e.g., garbage collection), as long as the pointers in + * the global "bip" structure point to the correct objects when + * the function returns. + */ +void * newPrimObject(int dataSize) { + ObjRef bigObjRef; + int size = sizeof(unsigned int) + dataSize * sizeof(unsigned char); + bigObjRef = malloc(size); + bigObjRef->size = size; + if (bigObjRef == NULL) { + fatalError("newPrimObject() got no memory"); + } + bigObjRef->size = size; + return bigObjRef; +} + +void * getPrimObjectDataPointer(void * obj){ + ObjRef oo = ((ObjRef) (obj)); + return oo->data; +} + diff --git a/bigint/tst/support.o b/bigint/tst/support.o new file mode 100644 index 0000000..2ad0cc0 Binary files /dev/null and b/bigint/tst/support.o differ diff --git a/bigint/tst/testbip b/bigint/tst/testbip new file mode 100755 index 0000000..02f1195 Binary files /dev/null and b/bigint/tst/testbip differ diff --git a/bigint/tst/testbip.c b/bigint/tst/testbip.c new file mode 100644 index 0000000..7c65754 --- /dev/null +++ b/bigint/tst/testbip.c @@ -0,0 +1,1253 @@ +/* + * testbip.c -- test the big integer processor + */ + + +#include +#include +#include + +#include "bigint.h" + +typedef struct { + unsigned int size; /* byte count of payload data */ + unsigned char data[1]; /* payload data, size as needed */ +} *ObjRef; + +/**************************************************************/ + + +void dump(char *prefix, ObjRef x, char *suffix) { + if (prefix != NULL && *prefix != '\0') { + printf("%s", prefix); + } + bigDump(stdout, x); + if (suffix != NULL && *suffix != '\0') { + printf("%s", suffix); + } +} + + +/**************************************************************/ + + +void test00(void) { + bigFromInt(0); + dump("+0x00000000 = ", bip.res, "\n"); + + bigFromInt(1); + dump("+0x00000001 = ", bip.res, "\n"); + + bigFromInt(2); + dump("+0x00000002 = ", bip.res, "\n"); + + bigFromInt(0x12); + dump("+0x00000012 = ", bip.res, "\n"); + + bigFromInt(0x123); + dump("+0x00000123 = ", bip.res, "\n"); + + bigFromInt(0x1234); + dump("+0x00001234 = ", bip.res, "\n"); + + bigFromInt(0x12345); + dump("+0x00012345 = ", bip.res, "\n"); + + bigFromInt(0x123456); + dump("+0x00123456 = ", bip.res, "\n"); + + bigFromInt(0x1234567); + dump("+0x01234567 = ", bip.res, "\n"); + + bigFromInt(0x12345678); + dump("+0x12345678 = ", bip.res, "\n"); + + bigFromInt(-0); + dump("-0x00000000 = ", bip.res, "\n"); + + bigFromInt(-1); + dump("-0x00000001 = ", bip.res, "\n"); + + bigFromInt(-2); + dump("-0x00000002 = ", bip.res, "\n"); + + bigFromInt(-0x12); + dump("-0x00000012 = ", bip.res, "\n"); + + bigFromInt(-0x123); + dump("-0x00000123 = ", bip.res, "\n"); + + bigFromInt(-0x1234); + dump("-0x00001234 = ", bip.res, "\n"); + + bigFromInt(-0x12345); + dump("-0x00012345 = ", bip.res, "\n"); + + bigFromInt(-0x123456); + dump("-0x00123456 = ", bip.res, "\n"); + + bigFromInt(-0x1234567); + dump("-0x01234567 = ", bip.res, "\n"); + + bigFromInt(-0x12345678); + dump("-0x12345678 = ", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test01(void) { + bigFromInt(0); + bip.op1 = bip.res; + printf("sign(+0x00000000) = %d\n", bigSgn()); + + bigFromInt(1); + bip.op1 = bip.res; + printf("sign(+0x00000001) = %d\n", bigSgn()); + + bigFromInt(2); + bip.op1 = bip.res; + printf("sign(+0x00000002) = %d\n", bigSgn()); + + bigFromInt(0x12); + bip.op1 = bip.res; + printf("sign(+0x00000012) = %d\n", bigSgn()); + + bigFromInt(0x123); + bip.op1 = bip.res; + printf("sign(+0x00000123) = %d\n", bigSgn()); + + bigFromInt(0x1234); + bip.op1 = bip.res; + printf("sign(+0x00001234) = %d\n", bigSgn()); + + bigFromInt(0x12345); + bip.op1 = bip.res; + printf("sign(+0x00012345) = %d\n", bigSgn()); + + bigFromInt(0x123456); + bip.op1 = bip.res; + printf("sign(+0x00123456) = %d\n", bigSgn()); + + bigFromInt(0x1234567); + bip.op1 = bip.res; + printf("sign(+0x01234567) = %d\n", bigSgn()); + + bigFromInt(0x12345678); + bip.op1 = bip.res; + printf("sign(+0x12345678) = %d\n", bigSgn()); + + bigFromInt(-0); + bip.op1 = bip.res; + printf("sign(-0x00000000) = %d\n", bigSgn()); + + bigFromInt(-1); + bip.op1 = bip.res; + printf("sign(-0x00000001) = %d\n", bigSgn()); + + bigFromInt(-2); + bip.op1 = bip.res; + printf("sign(-0x00000002) = %d\n", bigSgn()); + + bigFromInt(-0x12); + bip.op1 = bip.res; + printf("sign(-0x00000012) = %d\n", bigSgn()); + + bigFromInt(-0x123); + bip.op1 = bip.res; + printf("sign(-0x00000123) = %d\n", bigSgn()); + + bigFromInt(-0x1234); + bip.op1 = bip.res; + printf("sign(-0x00001234) = %d\n", bigSgn()); + + bigFromInt(-0x12345); + bip.op1 = bip.res; + printf("sign(-0x00012345) = %d\n", bigSgn()); + + bigFromInt(-0x123456); + bip.op1 = bip.res; + printf("sign(-0x00123456) = %d\n", bigSgn()); + + bigFromInt(-0x1234567); + bip.op1 = bip.res; + printf("sign(-0x01234567) = %d\n", bigSgn()); + + bigFromInt(-0x12345678); + bip.op1 = bip.res; + printf("sign(-0x12345678) = %d\n", bigSgn()); +} + + +/**************************************************************/ + + +void test02(void) { + int m[7]; + ObjRef n[7]; + int i, j; + int res; + + m[0] = 0; + bigFromInt(m[0]); + n[0] = bip.res; + printf("n[0] = %d\n", m[0]); + + m[1] = 100; + bigFromInt(m[1]); + n[1] = bip.res; + printf("n[1] = %d\n", m[1]); + + m[2] = -100; + bigFromInt(m[2]); + n[2] = bip.res; + printf("n[2] = %d\n", m[2]); + + m[3] = 101; + bigFromInt(m[3]); + n[3] = bip.res; + printf("n[3] = %d\n", m[3]); + + m[4] = -101; + bigFromInt(m[4]); + n[4] = bip.res; + printf("n[4] = %d\n", m[4]); + + m[5] = 12345678; + bigFromInt(m[5]); + n[5] = bip.res; + printf("n[5] = %d\n", m[5]); + + m[6] = -12345678; + bigFromInt(m[6]); + n[6] = bip.res; + printf("n[6] = %d\n", m[6]); + + for (i = 0; i < 7; i++) { + for (j = 0; j < 7; j++) { + printf("%12d ", m[i]); + bip.op1 = n[i]; + bip.op2 = n[j]; + res = bigCmp(); + if (res < 0) { + printf("<"); + } else + if (res > 0) { + printf(">"); + } else { + printf("="); + } + printf(" %12d", m[j]); + printf("\n"); + } + } +} + + +/**************************************************************/ + + +void test03(void) { + bigFromInt(0); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(1); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(-1); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(0x12345678); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(-0x12345678); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test04(void) { + int m[6]; + ObjRef n[6]; + int i, j; + + m[0] = +0x12345679; + m[1] = +0x12345678; + m[2] = +0x12345677; + m[3] = -0x12345677; + m[4] = -0x12345678; + m[5] = -0x12345679; + + for (i = 0; i < 6; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 6; i++) { + for (j = 0; j < 6; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigAdd(); + printf("%12d + %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test05(void) { + int m[5]; + ObjRef n[5]; + int i, j; + + m[0] = +0x12345678; + m[1] = +1; + m[2] = 0; + m[3] = -1; + m[4] = -0x12345678; + + for (i = 0; i < 5; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 5; i++) { + for (j = 0; j < 5; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigAdd(); + printf("%12d + %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test06(void) { + int m[6]; + ObjRef n[6]; + int i, j; + + m[0] = +0x12345679; + m[1] = +0x12345678; + m[2] = +0x12345677; + m[3] = -0x12345677; + m[4] = -0x12345678; + m[5] = -0x12345679; + + for (i = 0; i < 6; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 6; i++) { + for (j = 0; j < 6; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigSub(); + printf("%12d - %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test07(void) { + int m[5]; + ObjRef n[5]; + int i, j; + + m[0] = +0x12345678; + m[1] = +1; + m[2] = 0; + m[3] = -1; + m[4] = -0x12345678; + + for (i = 0; i < 5; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 5; i++) { + for (j = 0; j < 5; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigSub(); + printf("%12d - %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test08(void) { + int i; + + bigFromInt(1); + for (i = 1; i < 100; i++) { + bip.op1 = bip.res; + bip.op2 = bip.res; + bigAdd(); + printf("2 ^ %2d = ", i); + dump("", bip.res, "\n"); + } +} + + +/**************************************************************/ + + +void test09(void) { + int i, j; + + bigFromInt(2); + bip.op2 = bip.res; + for (i = 1; i < 10; i++) { + bip.res = bip.op2; + for (j = 1; j < i * i; j++) { + bip.op1 = bip.res; + bigMul(); + } + printf("2 ^ (%d ^ 2) = ", i); + dump("", bip.res, "\n"); + } +} + + +/**************************************************************/ + + +void factorial(int n) { + bigFromInt(1); + while (n > 0) { + bip.op1 = bip.res; + bigFromInt(n); + bip.op2 = bip.res; + bigMul(); + n--; + } +} + + +void test10(void) { + int i; + + for (i = 0; i < 100; i++) { + factorial(i); + printf("%2d! = ", i); + dump("", bip.res, "\n"); + } +} + + +/**************************************************************/ + + +void test11(void) { + int n, m; + + n = 5; + m = 0; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test12(void) { + int n, m; + + n = 12; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345677; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345677; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345677; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345677; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test13(void) { + int n, m; + + n = 12345678; + m = 1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = 17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = 255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = 1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = 17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = 255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = -1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = -17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = -255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = -1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = -17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = -255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test14(void) { + int n, m; + ObjRef dividend; + ObjRef divisor; + int ok; + + printf("divisor"); + for (m = 0; m < 256; m++) { + if (m % 8 == 0) { + printf("\n%3d to %3d: ", m, m + 7); + } + if (m == 0) { + printf(" "); + fflush(stdout); + continue; + } + bigFromInt(m); + divisor = bip.res; + ok = 1; + for (n = 0; n < (1 << 18); n++) { + bigFromInt(n); + dividend = bip.res; + bip.op1 = dividend; + bip.op2 = divisor; + bigDiv(); + bip.op1 = bip.res; + bigMul(); + free(bip.op1); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + free(bip.op1); + free(bip.op2); + bip.op1 = bip.res; + bip.op2 = dividend; + if (bigCmp() != 0) { + ok = 0; + } + free(bip.op1); + free(dividend); + } + free(divisor); + printf("%c", ok ? '.' : '?'); + fflush(stdout); + } + printf("\n"); +} + + +/**************************************************************/ + + +void test15(void) { + int n, m; + + n = 123456789; + m = (0xFF << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x80 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x7F << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x55 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x2F << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x18 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x0A << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x03 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x02 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x01 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test16(void) { + int n1, n2, n3, m; + + n1 = 0x12345678; + n2 = 0x66554433; + n3 = 12; + bigFromInt(n1); + bip.op1 = bip.res; + bigFromInt(n2); + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + bigFromInt(n3); + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + m = 0x5764; + bigFromInt(m); + bip.op2 = bip.res; + dump("", bip.op1, " / "); + dump("", bip.op2, " =\n"); + bigDiv(); + dump("", bip.res, " R. "); + dump("", bip.rem, "\n"); + bip.op1 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + dump("quotient * divisor + remainder =\n", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test17(void) { + /* prepare two big integers with 8 and 4 digits, respectively */ + bigFromInt(0x11111111); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + /* set all 8 digits of dividend */ + ((ObjRef) bip.op1)->data[5 + 0] = 0xF2; + ((ObjRef) bip.op1)->data[5 + 1] = 0xFB; + ((ObjRef) bip.op1)->data[5 + 2] = 0xE3; + ((ObjRef) bip.op1)->data[5 + 3] = 0x46; + ((ObjRef) bip.op1)->data[5 + 4] = 0x7C; + ((ObjRef) bip.op1)->data[5 + 5] = 0xC2; + ((ObjRef) bip.op1)->data[5 + 6] = 0x54; + ((ObjRef) bip.op1)->data[5 + 7] = 0xF8; + /* set )all 4 digits of divisor */ + ((ObjRef) bip.op2)->data[5 + 0] = 0x1B; + ((ObjRef) bip.op2)->data[5 + 1] = 0xE8; + ((ObjRef) bip.op2)->data[5 + 2] = 0xE7; + ((ObjRef) bip.op2)->data[5 + 3] = 0x8D; + /* divide */ + dump("", bip.op1, " / "); + dump("", bip.op2, " =\n"); + bigDiv(); + dump("", bip.res, " R. "); + dump("", bip.rem, "\n"); + /* verify */ + bip.op1 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + dump("quotient * divisor + remainder =\n", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test18(void) { + /* prepare two big integers with 8 and 4 digits, respectively */ + bigFromInt(0x11111111); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + /* set all 8 digits of dividend */ + ((ObjRef) bip.op1)->data[5 + 0] = 0x4D; + ((ObjRef) bip.op1)->data[5 + 1] = 0xCC; + ((ObjRef) bip.op1)->data[5 + 2] = 0x8C; + ((ObjRef) bip.op1)->data[5 + 3] = 0x18; + ((ObjRef) bip.op1)->data[5 + 4] = 0x34; + ((ObjRef) bip.op1)->data[5 + 5] = 0xDF; + ((ObjRef) bip.op1)->data[5 + 6] = 0x1D; + ((ObjRef) bip.op1)->data[5 + 7] = 0xFD; + /* set all 4 digits of divisor */ + ((ObjRef) bip.op2)->data[5 + 0] = 0x69; + ((ObjRef) bip.op2)->data[5 + 1] = 0xF4; + ((ObjRef) bip.op2)->data[5 + 2] = 0x94; + ((ObjRef) bip.op2)->data[5 + 3] = 0x37; + /* divide */ + dump("", bip.op1, " / "); + dump("", bip.op2, " =\n"); + bigDiv(); + dump("", bip.res, " R. "); + dump("", bip.rem, "\n"); + /* verify */ + bip.op1 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + dump("quotient * divisor + remainder =\n", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test19(void) { + int n, m; + + n = 0x7FFFFFFF; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = 0x00000001; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = 0x00000000; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = -0x00000001; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = -0x7FFFFFFF; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); +} + + +/**************************************************************/ + + +void test20(void) { + printf("please enter a number: "); + fflush(stdout); + bigRead(stdin); + dump("", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test21(void) { + bigFromInt(0); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(1); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-1); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(0x1234); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-0x1234); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(0x186A0); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-0x186A0); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(0x12345678); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-0x12345678); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(987654321); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + dump("", bip.res, " =\n"); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); +} + + +/**************************************************************/ + + +typedef struct { + void (*func)(void); + char *explanation; +} TestFunc; + + +TestFunc tests[] = { + { test00, "representation" }, + { test01, "sign" }, + { test02, "comparison" }, + { test03, "negation" }, + { test04, "addition, equal sizes" }, + { test05, "addition, different sizes" }, + { test06, "subtraction, equal sizes" }, + { test07, "subtraction, different sizes" }, + { test08, "2^n by addition" }, + { test09, "2^(n^2) by multiplication" }, + { test10, "factorial" }, + { test11, "division by zero" }, + { test12, "division, small dividend" }, + { test13, "division, single digit divisor" }, + { test14, "division, systematic test of simple cases" }, + { test15, "division, general case, different scale factors" }, + { test16, "division, general case, qhat (first guess)" }, + { test17, "division, general case, qhat (decremented twice)" }, + { test18, "division, general case, qhat (final correction)" }, + { test19, "conversion big --> int" }, + { test20, "read from file" }, + { test21, "print to file" }, +}; + +int numTests = sizeof(tests) / sizeof(tests[0]); + + +/**************************************************************/ + + +void usage(char *myself) { + int i; + + printf("Usage: %s \n", myself); + printf("valid test numbers are:\n"); + for (i = 0; i < numTests; i++) { + printf(" %2d: %s\n", i, tests[i].explanation); + } + exit(1); +} + + +int main(int argc, char *argv[]) { + int testNumber; + char *endp; + + if (argc != 2) { + usage(argv[0]); + } + testNumber = strtol(argv[1], &endp, 0); + if (*endp != '\0') { + usage(argv[0]); + } + if (testNumber < 0 || testNumber >= numTests) { + usage(argv[0]); + } + printf("Test %d: %s\n", testNumber, tests[testNumber].explanation); + (*tests[testNumber].func)(); + return 0; +} diff --git a/bigint/tst/testbip.o b/bigint/tst/testbip.o new file mode 100644 index 0000000..8acdffd Binary files /dev/null and b/bigint/tst/testbip.o differ diff --git a/njvm.o b/njvm.o index faea6d5..649cde9 100644 Binary files a/njvm.o and b/njvm.o differ diff --git a/objref.c b/objref.c index 19a75d1..82aca28 100644 --- a/objref.c +++ b/objref.c @@ -4,8 +4,8 @@ typedef struct ObjRef{ // if brkokenHeart and forward_pointer added at this point bip throws errors -// bool brokenHeart; -// struct ObjRef *forward_pointer; + bool brokenHeart; + struct ObjRef *forward_pointer; unsigned int size; unsigned char data[1]; } *ObjRef;