Need Help for my homework
Im doing a calculator.
Im stucked for few days..
Asking for help.
For the add and sub function.
Code:
/***************************************************************
* This program reads performs arithmetic operations
* (?, +, - and *)on integers in an arbitrary base number
* system. (Base 2 to 36).
***************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/* the maximum number of digits in an arbitrary base number */
#define MAXDIGITS 16
/* global variables */
int g_base = 10;
FILE *g_inputFile;
/* a data structure used for arbitrary base numbers */
typedef struct {
char negative;
char digit[MAXDIGITS];
} NumberType;
/* function prototypes */
NumberType add( NumberType arg1, NumberType arg2 );
NumberType subtract( NumberType arg1, NumberType arg2 );
NumberType multiply( NumberType arg1, NumberType arg2 );
/* Note: isspace(x) is a macro defined in the header file "ctype.h".
If you had to code it yourself as a C function, it would be something like this:
int isspace( char c ) {
return c == ' ' || c == '\t' || c == '\r' || c == '\n':
}
*/
/***************************************************************
* Function: printNumber( NumberType number )
*
* Inputs:
* number: a number in an arbitrary base
*
* Global variables used:
* g_base: the number system base
*
* Output: None
*
* Description:
* The function outputs the number supplied as an argument,
* printing it to the standard output. Redundant leading
* zeros are suppressed when printing.
* Each digit is checked that it is on the correct range for the
* current number system base before being printed.
***************************************************************/
void printNumber( NumberType number ) {
/* skip over leading zeros in the number */
// STEP 2: Add code to print a number.
int i;
i = 0;
while(number.digit[i] == 0 && i != MAXDIGITS-2) {
i++;
}
if(number.negative != 0) {
printf("-");
}
for(i; i<MAXDIGITS-1; i++){
printf("%d",number.digit[i]);
}
}
/***************************************************************
* Temp Function: randomNumber()
*
* Inputs: None
*
* Global variables used:
* g_base: the number system base
*
* Output: a value of type NumberType representing an arbitrary
* base number which has been read from an input file.
*
* Description:
* Delete this function before you hand in your code. It simply
* returns a randomly generated number in teh proper format.
***************************************************************/
NumberType randomNumber() {
int c, i, numDigits, digitVal;
NumberType result;
char digitSequence[MAXDIGITS];
/* initialize the storage for the result */
result.negative = 0;
for( i = 0; i < MAXDIGITS; i++ ) {
result.digit[i] = 0;
}
if((rand()% 2) == 0)
result.negative = 1;
for( i = 8; i < MAXDIGITS; i++ ) {
result.digit[i] = (rand() % g_base);
}
return result;
}
/***************************************************************
* Function: readNumber()
*
* Inputs: None
*
* Global variables used:
* g_base: the number system base
* g_inputFile -- an open input stream from which input is read.
*
* Output: a value of type NumberType representing an arbitrary
* base number which has been read from an input file.
*
* Description:
* This procedure compares the value of two numbers in base
* g_base
*
* Note:
* Skips over white space characters and then inputs a number
* which has the lexical structure
* ['+' | '-'] digit+
* where digit is a character from the set
* {'0'-'9','A'-'Z','a'-'z'}
* to represent a digit in the given base.
***************************************************************/
NumberType readNumber( ) {
// Step 12: (After lab 3). Get input from file rather than these random values.
return randomNumber();
}
/***************************************************************
* Procedure: compareMagnitude(NumberType arg1, NumberType arg2 )
*
* Inputs:
* arg1: an arbitrary base number
* arg2: a second arbitrary base number
*
* Global variables used:
* g_base: the number system base
*
* Output: an integer which is:
* negative if |arg1| < |arg2|,
* zero if |arg1| = |arg2|,
* or positive if |arg1| > |arg2|.
*
* Description:
* This procedure compares the absolute value of two numbers in
* base g_base
*
***************************************************************/
int compareMagnitude( NumberType arg1, NumberType arg2 ) {
// STEP 3: Add code to compare the magnitude of 2 numbers.
int i;
arg1.negative = arg2.negative;
for (i = 0; i< MAXDIGITS; i++) {
if (arg1.digit[i] > arg2.digit[i]) {
return 1;
}else if (arg1.digit[i] < arg2.digit[i]) {
return -1;
}
}
if (arg1.digit[MAXDIGITS] == arg2.digit[MAXDIGITS]) {
return 0;
}
}
/***************************************************************
* Procedure: compare( NumberType arg1, NumberType arg2 )
*
* Inputs:
* arg1: an arbitrary base number
* arg2: a second arbitrary base number
*
* Global variables used:
* g_base: the number system base
*
* Output: an integer which is:
* negative if arg1 < arg2,
* zero if arg1 = arg2,
* or positive if arg1 > arg2.
*
* Description:
* This procedure compares the value of two numbers in base
* g_base
***************************************************************/
int compare( NumberType arg1, NumberType arg2 ) {
// STEP 4: Add code to compare 2 numbers.
// Hint: If both numbers are postive compareMagnitude
// If both numbers are negitive compareMagnitude (remember -4>-7)
// If one is positive and the other is negitive then the postive
// arguemtn is greater except -0 = 0.
if (arg1.negative == 0 && arg2.negative ==0) {
return compareMagnitude(arg1,arg2);
}else if (arg1.negative !=0 && arg2.negative !=0) {
return -1*compareMagnitude(arg1,arg2);
}else if (arg1.negative == 0 && arg2.negative != 0) {
if (arg1.negative == arg2.negative){
return 0;
}
return 1;
}else if (arg1.negative != 0 && arg2.negative == 0) {
if (arg1.negative == arg2.negative){
return 0;
}
return -1;
}else{
return 0;
}
}
/***************************************************************
* Procedure: NumberType add( NumberType arg1, NumberType arg2 )
*
* Inputs:
* arg1: an arbitrary base number
* arg2: a second arbitrary base number
*
* Global variables used:
* g_base: the number system base
*
* Output: an arbitrary base number equal to arg1+arg2.
*
* Description:
* This procedure adds arg1 and arg2 in base g_base
*
* Notes:
* It is assumed that the two arguments are valid (i.e.
* that all digits are in the range 0 to g_base-1 in value).
* If an overflow occurs (i.e. the result does not fit into the
* array of digits provided), an error message is printed and
* the program halts.
***************************************************************/
NumberType add( NumberType arg1, NumberType arg2 ) {
NumberType result;
int i, carry, sum;
/* if the arguments have opposite signs, use the subtract function */
// STEP 5: Add code to compare the signs of 2 numbers.
if(arg1.negative == 0 && arg2.negative != 0){
sum = compareMagnitude(arg1,arg2);
if (sum = 1) {
arg2.negative = 0;
}else {
arg1.negative = 1;
}
return subtract(arg1, arg2);
}
if(arg1.negative != 0 && arg2.negative == 0){
sum = compareMagnitude(arg1, arg2);
if (sum = 1) {
arg2.negative = 1;
}else {
arg1.negative = 0;
}
return subtract(arg1, arg2);
}
/* to get here, both arguments must have the same sign */
// STEP 6: add two numbers
if (arg1.negative == 0 && arg2.negative ==0) {
for (i = MAXDIGITS-1; i >= 0; i--) {
result.digit[i] = arg1.digit[i] + arg2.digit[i];
if (result.digit[i] >= g_base) {
result.digit[i] = result.digit[i]-g_base;
arg1.digit[i-1]= arg1.digit[i-1]+1;
}
}
result.negative = 0;
return result;
}
if (arg1.negative != 0 && arg2.negative != 0) {
for (i = MAXDIGITS-1; i >= 0; i--) {
result.digit[i] = arg1.digit[i]+arg2.digit[i];
if (result.digit[i] >= g_base) {
result.digit[i] = result.digit[i]-g_base;
arg1.digit[i-1]= arg1.digit[i-1]+1;
}
}
result.negative = 1;
return result;
}
return result;
}
/***************************************************************
* NumberType subtract( NumberType arg1, NumberType arg2 )
*
* Inputs:
* arg1: an arbitrary base number
* arg2: a second arbitrary base number
*
* Global variables used:
* g_base: the number system base
*
* Output: an arbitrary base number equal to arg1-arg2.
*
* Description:
* This procedure subtracts arg2 from arg1 in base g_base
*
* Notes:
* It is assumed that the two arguments are valid (i.e.
* that all digits are in the range 0 to g_base-1 in value).
* If an overflow occurs (i.e. the result does not fit into the
* array of digits provided), an error message is printed and
* the program halts.
***************************************************************/
NumberType subtract( NumberType arg1, NumberType arg2 ) {
NumberType result;
int i, borrow, diff;
/* if the arguments have opposite signs, use the add function */
// STEP 7: Add code to compare the signs of 2 numbers.
if(arg1.negative == 0 && arg2.negative != 0){
arg2.negative = 0;
return add(arg1, arg2);
}else if(arg1.negative != 0 && arg2.negative == 0){
arg2.negative = 1;
return add(arg1, arg2);
}
/* to get here, both arguments have the same sign; now we
want to subtract the smaller in magnitude from the larger
and give the result the appropriate sign.
*/
// STEP 8: subtract the smaller in magnitude from the larger
diff = compareMagnitude(arg1,arg2);
borrow = 0;
if (diff == -1) {
NumberType temp;
temp = arg1;
arg1 = arg2;
arg2 = temp;
}
if (arg1.negative == 0 && arg2.negative == 0) {
for (i = MAXDIGITS-1; i>=0 ; i--) {
if (arg1.digit[i]<arg2.digit[i]) {
arg1.digit[i] = arg1.digit[i]+g_base;
arg1.digit[i-1] = arg1.digit[i-1];
}
result.digit[i] = arg1.digit[i]-arg2.digit[i];
}
if (diff = -1){
result.negative = 1;
}else {
result.negative = 0;
}
return result;
}
if (arg1.negative != 0 && arg2.negative != 0) {
for (i = MAXDIGITS-1; i>=0 ; i--) {
if (arg1.digit[i]<arg2.digit[i]) {
arg1.digit[i] = arg1.digit[i]+g_base-1;
arg1.digit[i-1] = arg1.digit[i-1]-1;
}
result.digit[i] = arg1.digit[i]-arg2.digit[i];
}
if (diff = -1) {
result.negative = 0;
}else {
result.negative = 1;
}
return result;
}
return result;
}
/***************************************************************
* Procedure: NumberType multiplyByDigit(NumberType arg1, int d )
*
* Inputs:
* arg1: an arbitrary base number
* d: a small integer in the range 0 to g_base-1
*
* Global variables used:
* g_base: the number system base
*
* Output: an arbitrary base number equal to arg1*d
*
* Description:
* This procedure multiplies arg1 by d
***************************************************************/
NumberType multiplyByDigit( NumberType arg1, int d ) {
NumberType result;
int i, carry;
// STEP 10: multiply the number by a single digit number
for (i = MAXDIGITS-1; i >= 0; i--) {
result.digit[i] = arg1.digit[i]*d;
}
for (i = MAXDIGITS-1; i >= 0; i--) {
if (result.digit[i] >= g_base) {
result.digit[i] = result.digit[i]-g_base;
result.digit[i-1] = result.digit[i-1]+1;
}
}
return result;
}
/***************************************************************
* Procedure: NumberType shiftLeft( NumberType arg1 )
*
* Inputs:
* arg1: an arbitrary base number
*
* Global variables used:
* g_base: the number system base
*
* Output: an arbitrary base number equal to arg1*g_base.
*
* Description:
* This procedure multiplies arg1 and g_base
***************************************************************/
NumberType shiftLeft( NumberType arg1 ) {
NumberType result;
int i;
// STEP 9: shift all the digits of a number left.
int temp;
for (i = MAXDIGITS-1; i >=0 ; i-- ) {
result.digit[i-1] = arg1.digit[i];
}
result.digit[MAXDIGITS-1] = 0;
return result;
}
/***************************************************************
* Procedure: NumberType multiply( NumberType arg1,
* NumberType arg2 )
*
* Inputs:
* arg1: an arbitrary base number
* arg2: a second arbitrary base number
*
* Global variables used:
* g_base: the number system base
*
* Output: an arbitrary base number equal to arg1*arg2.
*
* Description:
* This procedure multiplies arg1 and arg2 in base g_base
*
* Notes:
* It is assumed that the two arguments are valid (i.e.
* that all digits are in the range 0 to g_base-1 in value).
* If an overflow occurs (i.e. the result does not fit into the
* array of digits provided), an error message is printed and
* the program halts.
***************************************************************/
NumberType multiply( NumberType arg1, NumberType arg2 ) {
NumberType result;
int i, d;
NumberType a, b;
// STEP 11: multiply the two numbers
/* clear result digits to zero */
/* sign of result is negative if arg1 & arg2 have different signs */
/* force arg1 to same sign as result so that calls to the add function
inside the loop do not become subtractions */
for (i = 0; i < MAXDIGITS; i++) {
result.digit[i] = 0;
}
if (arg1.negative == 0 && arg2.negative == 0) {
result.negative == 0;
}else if (arg1.negative != 0 && arg2.negative != 0) {
result.negative == 0;
arg1.negative == 0;
}else {
result.negative == 1;
arg1.negative == 0;
}
for (i = MAXDIGITS-1; i >= 0; i--) {
d = arg2.digit[i];
a = shiftLeft(arg1);
b = multiplyByDigit(arg1, d);
result.digit[i] = a.digit[i] + b.digit[i];
}
return result;
}
/***************************************************************
* Procedure: processInput()
*
* Inputs: None
*
* Global variables used:
* g_inputfile: the stream used as the source of input
* g_base: the number system base
*
* Output: None
*
* Description:
* This function repeatedly reads input from inputfile, decodes
* that input as commands to set the number system base or to
* perform arithmetic operations and interprets those commands,
* outputting the results to the standard output.
***************************************************************/
void processInput() {
NumberType arg1, arg2, result;
// Step 12: (After lab 3). Get input from file rather than these random values.
// Set up random number generator for random input. Remove!!
long ltime;
int stime;
ltime = time(NULL); stime = (unsigned) ltime/2; srand(stime);
g_base = 16;
printf(" base = %d\n", g_base);
arg1 = readNumber();
arg2 = readNumber();
printNumber(arg1);
if(compare( arg1, arg2 ) < 0)
printf(" < ");
if(compare( arg1, arg2 ) == 0)
printf(" = ");
if(compare( arg1, arg2 ) > 0)
printf(" > ");
printNumber(arg2); printf("\n");
printf("|"); printNumber(arg1);printf("|");
if(compareMagnitude( arg1, arg2 ) < 0)
printf(" < ");
if(compareMagnitude( arg1, arg2 ) == 0)
printf(" = ");
if(compareMagnitude( arg1, arg2 ) > 0)
printf(" > ");
printf("|");printNumber(arg2); printf("|");printf("\n");
printNumber(arg1); printf(" + "); printNumber(arg2); printf(" = "); printNumber(add(arg1,arg2)); printf("\n");
printNumber(arg1); printf(" - "); printNumber(arg2); printf(" = "); printNumber(subtract(arg1,arg2)); printf("\n");
printNumber(arg1); printf(" * "); printNumber(arg2); printf(" = "); printNumber(multiply(arg1,arg2)); printf("\n");
}
/***************************************************************
* Procedure: main( int argc, char *argv[] )
*
* Inputs: argc - The number of arguments in argv
* - If argc == 1, the only arguement is
* the executable name so there is no
* input file: use stdin.
* argv -arguments are passed by the operating
* system
* (see a Unix manual for their meaning.)
* - If argc == 1, the second arguement (argv[1])
* is the input file
*
* Output: 0 indicates successful completion to the operating
* system.
*
* Description:
* Entry point for the program.
***************************************************************/
int main( int argc, char *argv[] ) {
// Step 1: update the welcome message:
printf("Hi,\n");
if (argc == 1) {
g_inputFile = stdin;
} else if (argc == 2) {
g_inputFile = fopen(argv[1], "r");
if (g_inputFile == NULL) {
fprintf(stderr, "*** unable to open file %s for input\n", argv[1]);
exit(1);
}
} else {
fprintf(stderr, "*** program can be invoked with at most one argument\n");
exit(1);
}
processInput();
printf("ByeBye~\n");
return 0;
}