#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 10001 struct integer { int* digits; int size; }; struct integer* add(struct integer* one, struct integer *two); void print(struct integer* number); void print_op(struct integer* op1, struct integer* op2,struct integer* tempwer,char op); struct integer* convert_integer(char* word); void free_struct(struct integer* thisint); struct integer* multiply(struct integer *p, struct integer *q); int main() { FILE* ifp = fopen("bigint.txt", "r"); int loop, numcases; fscanf(ifp, "%d", &numcases); // Go through each case. for (loop=1; loop<=numcases; loop++) { // Read in both operands. char op1[MAX]; char op2[MAX]; fscanf(ifp, "%s%s", op1, op2); // Convert and compute. struct integer* first = convert_integer(op1); struct integer* second = convert_integer(op2); struct integer* ans = multiply(first, second); printf("Problem #%d: ", loop); print_op(first, second, ans, '*'); printf("\n"); // After we output, we don't need these any more. free_struct(first); free_struct(second); free_struct(ans); } return 0; } /* Pre-conditions: Both one and two are not NULL pointers that point to linked lists structures that store non-negative digits at each node. Post-conditions: A pointer to a linked list will be returned. The linked list will store the value of the sum of the two integers represented by the linked lists passed into the function. */ struct integer* add(struct integer* one, struct integer *two) { struct integer *ans; int digit1 = 0, digit2 = 0, carry = 0, result, i; ans = (struct integer *)malloc(sizeof(struct integer)); //allocate space for the larger of the 2 arrays if(one->size>two->size) ans->size=one->size; else ans->size=two->size; ans->digits=(int*)(malloc(sizeof(int)*ans->size)); for(i=0;i<ans->size;i++) { // Determine digit to add from first operand. if (i<one -> size) digit1 = one -> digits[i]; else digit1 = 0; // Determine digit to add from second operand. if (i<two -> size) digit2 = two -> digits[i]; else digit2 = 0; // Compute correct addition digit and carry. result = (digit1 + digit2 + carry)%10; carry = (digit1 + digit2 + carry)/10; // Store result in the appropriate linked list. ans -> digits[i] = result; } // Take care of the most significant digit if there is a carry. if (carry != 0) { /* copy off the whole array into a new one of size+1 and free the old one in case of carry */ ans->size+=1; ans->digits = (int *)realloc(ans->digits, sizeof(int)*ans->size); ans->digits[ans->size-1] = carry; } // Return the ptr. to the added result. return ans; } /* Precondition: number points to a not NULL linked list that contains only single digits stored at each node. Postcondition: The integer represented by the linked list pointed to by number will be printed out. */ void print(struct integer* number) { int i; if (number != NULL) { // Loop through in backwards order, since number is stored reversed. for(i=number->size-1;i>=0;i--) { printf("%d",number->digits[i]); } } } /* Precondition: op1 and op2 point to valid linked lists storing integers, operator is a valid integer operator, and tempwer is the value of applying the first operation to the second. Postcondition: The arithmetic operation desired (op1 operator op2) will be printed to the screen in a reasonable manner. */ void print_op(struct integer* op1, struct integer* op2,struct integer* tempwer,char op) { print(op1); printf(" %c ", op); print(op2); printf(" = "); print(tempwer); } /* Preconditions: the first parameter is a pointer to a pointer variable that points to struct integer. The function skips leading blanks and assumes that no leading zeros are entered at the input. Postconditions: The function will read the digits of the large integer character by character, convert them into integers and place them in nodes of a linked list. The pointer to the head of the list is returned as the value of the input parameter. */ struct integer* convert_integer(char* word) { int i; struct integer *ans=(struct integer *)(malloc(sizeof(struct integer))); ans->size=0; if(word==NULL) ans->digits=NULL; else { // Allocate space for each of the digits. ans->size = strlen(word); ans->digits=(int *)(malloc(sizeof(int)*ans->size)); // Store them in reverse order. for(i=0;i< ans->size;i++) ans->digits[ans->size-i-1]=word[i] - '0'; } //if word not NULL return ans; } /* Preconditions: p and q are pointers to struct integers. Postconditions: A new struct integer is created that stores the product of the integers pointed to by p and q and a pointer to it is returned. */ struct integer* multiply(struct integer *p, struct integer *q) { struct integer *temp; struct integer *ans; int digit1 = 0, digit2 = 0, carry = 0, index=0, front=0, result, i, j, pos, preSize; temp = (struct integer *)calloc(sizeof(struct integer),1); ans = (struct integer *)calloc(sizeof(struct integer),1); //allocate space for the larger of the 2 arrays //Whichever array is larger will be the starting size of the tempwer array. if(q->size>p->size) temp->size = q->size; else temp->size = p->size; temp->digits=(int*)(calloc(sizeof(int)*temp->size,1)); //use a double for loop, one for the top number and one for bottom. for(i=0; i<q->size; i++) { //Make the starting size the size of the biggest number. if(q->size>p->size) temp->size = q->size; else temp->size = p->size; temp->digits=(int*)(calloc(sizeof(int)*temp->size,1)); if (i < q->size) digit1 = q->digits[i]; else digit1 = 0; //Bottom part of the multiplication. for(j=0; j<p->size; j++) { // Determine digit to add from first operand. if (j < p->size) digit2 = p->digits[j]; else digit2 = 0; // Compute correct multiplication digit and carry. //gives last digit result = (digit1 * digit2 + carry)%10; //drops last digit carry = (digit1 * digit2 + carry)/10; // Store result in the appropriate linked list. temp -> digits[j] = result; } //Add a zero to the end of the next number (like multiplying by hand. if(i>0) { temp->size += i; temp->digits = (int *)(realloc(temp->digits, sizeof(int)*temp->size)); for(j=temp->size; j>0; j--) { if((j-1-i)<0) break; //Shift everthing over by 1. else temp->digits[j-1]=temp->digits[j-1-i]; } //Make the new number zero. for(j=1; j<=i; j++) temp -> digits[j-1] = 0; } //If there is a carry insert it in front of the number. if (carry != 0) { temp->size += 1; temp->digits = (int *)(realloc(temp->digits, sizeof(int)*temp->size)); temp->digits[temp->size-1]=0; //Find the front of the number. for(j=temp->size; j>0; j--) { if(temp->digits[j-1] != 0) { front = j; break; } } //Insert it. if(result == 0) temp->digits[front+1] = carry; else temp->digits[front] = carry; carry = 0; } //Delete any leading zeros. if(temp->size != 1) { for(j=temp->size; j>0; j--) { //Finds where the zeros end. if(temp->digits[j-1] != 0) { pos =j; break; } //Counts the zeros. if(temp->digits[j-1] == 0) index++; } //If they are all zeros then make the temp number 0 of size 1. if(index==temp->size) { pos=1; temp->size = temp->size-(temp->size-pos); temp->digits = (int *)realloc(temp->digits, sizeof(int)*temp->size); } //If not then reallocate with the extra zeros removed. else { temp->size = temp->size-(temp->size-pos); temp->digits = (int *)realloc(temp->digits, sizeof(int)*temp->size); } index=0; } //If this is the first time saving the answer the allocate memory for it. if(i==0) { ans->size = temp->size; ans->digits=(int*)(calloc(sizeof(int)*temp->size,1)); } //Add the temp number to the total (ans). ans = add(temp, ans); //Clear temp. for(j=0; j<temp->size; j++) temp->digits[j]=0; } //for on top free_struct(temp); return ans; } // Frees the memory for the struct pointed to by thisint. void free_struct(struct integer* thisint) { free(thisint->digits); free(thisint); }
\\a.txt
\\----------
\\Output Code: 0
\\Matched Answer: True
\\Your Output:
\\Problem #1: 1 * 5 = 5
\\Problem #2: 10 * 20 = 200
\\--------------------
\\b.txt
\\----------
\\Output Code: 0
\\Matched Answer: False
\\Your Output:
\\Problem #1: 30 * 40 = 1200
\\Problem #2: 500 * 600 = 30
\\--------------------