Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Jevin Olano
- // jolano
- // CSE 101
- // November 9, 2019
- // BigInteger.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
- #include <math.h>
- #include "BigInteger.h"
- const int POWER = 9;
- const int BASE = 1000000000;
- // Constructors & Destructors ---------------------------
- // newBigInteger()
- // Returns a reference to a new BigInteger object in the zero state.
- BigInteger newBigInteger() {
- BigInteger bi = malloc(BigIntegerObj);
- bi->number = newList();
- bi->sign = 0;
- return bi;
- }
- // freeBigInteger()
- // Frees heap memory associated with *pN, sets *pN to NULL.
- void freeBigInteger(BigInteger* pN) {
- BigInteger N = *pN;
- makeZero(N);
- free(N);
- N = NULL;
- }
- // Access Functions -------------------------------------
- // sign()
- // Returns -1 if N is negative, 1 if N is positive, and 0 if N is in the zero state.
- int sign(BigInteger N) {
- return N->sign;
- }
- // compare()
- // Returns -1 if A<B, 1 if A>B, and 0 if A=B.
- int compare(BigInteger A, BigInteger B) {
- if (A->sign == 0 && B->sign == 0) {
- return 0; // if both A & B are in the zero state
- }
- if (A->sign > B->sign) {
- return 1; // if A is positive and B is negative
- }
- if (A->sign < B->sign) {
- return -1; // if A is negative and B is positive
- }
- int lengthA = length(A->number);
- int lengthB = length(B->number);
- if (lengthA > lengthB && A->sign == 1) {
- return 1; // if both A & B are positive and A is longer than B
- }
- if (lengthA > lengthB && A->sign == -1) {
- return -1; // if both A & B are negative and A is longer than B
- }
- if (lengthB > lengthA && B->sign == 1) {
- return -1; // if both A & B are positive and B is longer than A
- }
- if (lengthB > lengthA && B-sign == -1) {
- return 1; // if both A & B are negative and B is longer than A
- }
- // at this point, A & B must be the same sign
- moveFront(A->number);
- moveFront(B->number);
- while (get(A->number) != NULL) {
- int digitA = get(A->number);
- int digitB = get(B->number);
- if (digitA > digitB && A->sign == 1) {
- return 1;
- }
- if (digitA < digitB && A->sign == 1) {
- return -1;
- }
- if (digitA > digitB && A->sign == -1) {
- return -1;
- }
- if (digitA < digitB && A->sign == -1) {
- return 1;
- }
- moveNext(A->number);
- moveNext(B->number);
- }
- return 0;
- }
- // equals()
- // Return true (1) if A and B are equal, false (0) otherwise.
- int equals(BigInteger A, BigInteger B) {
- return compare(A, B) == 0 ? 1 : 0;
- }
- // Manipulation Procedures ------------------------------
- // makeZero()
- // Re-sets N to the zero state.
- void makeZero(BigInteger N) {
- clear(N->number);
- N->sign = 0;
- }
- // negate()
- // Reverses the sign of N: positive <--> negative. Does nothing if N is in the zero state.
- void negate(BigInteger N) {
- N->sign *= -1;
- }
- // BigInteger Arithmetic Operations ---------------------
- // stringToBigInteger()
- // Returns a reference to a new BigInteger represented in base 10 by the string s.
- // Pre: s is a non-empty string containing only base ten digits {0,1,2,3,4,5,6,7,8,9}
- // and an optional sign {+, -} prefix.
- BigInteger stringToBigInteger(char* s) {
- BigInteger bi = newBigInteger();
- // handles input = '0'
- if (strlen(s) == 1 && s[0] == '0') {
- return bi;
- }
- // p is basically a cursor
- char *p = s;
- // checks optional sign prefixes
- if (s[0] == '+') {
- bi->sign = 1;
- p++;
- } else if (s[0] == '-') {
- bi->sign = -1;
- p++;
- }
- // check for incomplete digit (incomplete chunk)
- int remainder = strlen(p) % POWER;
- if (remainder > 0) {
- append(bi->number, strToLong(p, remainder));
- p += remainder;
- }
- // add "full" digits
- int numDigitsLeft = strlen(p) / POWER;
- for (int i = 0; i < numDigitsLeft; i++) {
- append(bi->number, strToLong(p, POWER));
- p += POWER;
- }
- return bi;
- }
- // private helper
- long strToLong(char *s, long numChars) {
- char buffer[10];
- buffer[0] = '\0';
- strncat(buffer, s, numChars);
- return strtol(s, NULL, 10);
- }
- // copy()
- // Returns a reference to a new BigInteger object in the same state as N.
- BigInteger copy(BigInteger N) {
- BigInteger copyInt = newBigInteger();
- copyInt->sign = N->sign;
- copyInt->number = copyList(N->number);
- return copyInt;
- }
- // add()
- // Places the sum of A and B in the existing BigInteger S, overwriting its current state: S = A + B
- void add(BigInteger S, BigInteger A, BigInteger B) {
- int freeBeforeAssigning = (S == A || S == B) ? 1 : 0;
- BigInteger sumInt = sum(A, B);
- if (freeBeforeAssigning) {
- freeBigInteger(&S);
- }
- S = sumInt;
- }
- // sum()
- // Returns a reference to a new BigInteger object representing A + B.
- BigInteger sum(BigInteger A, BigInteger B) {
- if (A->sign == 0 && B->sign == 0) {
- return newBigInteger();
- }
- if (A->sign == 0) {
- return copy(B);
- }
- if (B->sign == 0) {
- return copy(A);
- }
- if (A->sign == 1 && B-sign == -1) {
- return diff(A, B);
- }
- if (A->sign == -1 && B-sign == 1) {
- return diff(B, A);
- }
- BigInteger sumInt = newBigInteger();
- // TODO: the actual arithmetic here
- sumInt->sign = A->sign; // or B->sign since they're the same
- return sumInt;
- }
- // subtract()
- // Places the difference of A and B in the existing BigInteger D, overwriting its current state: D = A - B
- void subtract(BigInteger D, BigInteger A, BigInteger B) {
- int freeBeforeAssigning = (D == A || D == B) ? 1 : 0;
- BigInteger diffInt = diff(A, B);
- if (freeBeforeAssigning) {
- freeBigInteger(&D);
- }
- D = diffInt;
- }
- // diff()
- // Returns a reference to a new BigInteger object representing A - B.
- BigInteger diff(BigInteger A, BigInteger B) {
- if (A->sign == 0 && B->sign == 0) {
- return newBigInteger();
- }
- if (A->sign == 0) {
- BigInteger negativeB = copy(B);
- negate(negativeB);
- return negativeB;
- }
- if (B->sign == 0) {
- return copy(A);
- }
- }
- // multiply()
- // Places the product of A and B in the existing BigInteger P, overwriting its current state: P = A * B
- void multiply(BigInteger P, BigInteger A, BigInteger B) {
- int freeBeforeAssigning = (P == A || P == B) ? 1 : 0;
- BigInteger prodInt = prod(A, B);
- if (freeBeforeAssigning) {
- freeBigInteger(&P);
- }
- P = prodInt;
- }
- // prod()
- // Returns a reference to a new BigInteger object representing A * B.
- BigInteger prod(BigInteger A, BigInteger B) {
- if (A->sign == 0 || B->sign == 0) {
- return newBigInteger();
- }
- }
- // Other Operations -------------------------------------
- // printBigInteger()
- // Prints a base 10 string representation of N to filestream out.
- void printBigInteger(FILE* out, BigInteger N) {
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement