# Thread: Need Help for my homework

1. ## Need Help for my homework

Im doing a calculator.
Im stucked for few days..
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;
}
/***************************************************************
*
* 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.
***************************************************************/

// 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;
}else if(arg1.negative != 0 && arg2.negative == 0){
arg2.negative = 1;
}
/* 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);

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;
}```

2. What exactly do you need help with? Other than this:
Code:
```		if (sum = 1) {
arg2.negative = 0;```
Use = to assign a value, == to test for equality.

Quzah.

3. Thank you for pointing that.

This is my output if I ran my code under base 10.

Code:
```Hi.
base = 10
4  >  0
|4|  >  |0|
4  +  0  =  5
4  -  0  =  -4
4  *  0  =  -48
ByeBye~```
Really need help...
And could you please look at my compare too?
I found that sometime output gives like

6 > -6
|6| > |-6|

Thanks..

4. I'm just wondering how much of this is tutor boilerplate code, and how much of it is original work from the OP.

Or perhaps whether ALL of it is from the tutor, and the point of the exercise is to find all the places where == vs. = are screwed up (I counted at least half a dozen).

Not to mention another half dozen or so array under-run errors.

The problem with tutor boilerplate code is that it's like "paint by numbers". You only learn how to fill in the blanks, once someone else has done the interesting bit of laying all the groundwork.
OK to begin with, but by the time you're at a program of this complexity, you should really be doing most of it yourself.

5. Did you fix the error (which occurs multiple times)? Are you providing the numbers, or is your random number generator really good at giving you zeroes?