/* June 30, 1998 */ /* Case Study: Arithmetic with Common Fractions */ /* Program that can add, subtract, multiply, divide two fractions input by the user */ #include #include /* provides fucntion abs */ /* Function Prototypes */ void scan_fraction (int *nump, int *denomp); char get_operator(void); void add_fractions (int n1, int d1, int n2, int d2, int *n_ansp, int *d_ansp); void multiply_fractions (int n1, int d1, int n2, int d2, int *n_ansp, int *d_ansp); int find_gcd (int n1, int n2); void reduce_fraction (int *nump, int *denomp); void print_fraction (int num, int denom); main () { int n1, d1; int n2, d2; char op; char again; int n_ans, d_ans; /* Get Input */ do { /* Get a fraction problem */ scan_fraction (&n1, &d1); op = get_operator(); scan_fraction (&n2, &d2); /* Computes the result */ switch (op) { case '+': add_fractions (n1, d1, n2, d2, &n_ans, &d_ans); break; case '-': add_fractions (n1, d1, -n2, d2, &n_ans, &d_ans); break; case '*': multiply_fractions (n1, d1, n2, d2, &n_ans, &d_ans); break; case '/': multiply_fractions (n1, d1, d2, n2, &n_ans, &d_ans); } reduce_fraction(&n_ans, &d_ans); /* Displays problem and result */ printf ("\n"); print_fraction (n1, d1); printf (" %c ", op); print_fraction (n2, d2); printf (" = "); print_fraction(n_ans, d_ans); /* Asks user about doing another problem */ printf ("\nDo another problem? (y/n)> "); scanf (" %c", &again); } while (again == 'y' || again == 'Y'); } /* Gets and returns a valid fraction as its result */ void scan_fraction (int *nump, int *denomp) { char slash; int status; int error; char discard; do { /* No errors detected yet */ error = 0; /* Get a fraction from the user */ printf ("Enter a common fraction as two integers "); printf ("separated by a slash> "); status = scanf ("%d %c%d", nump, &slash, denomp); /* Validate the function */ if (status < 3) { error = 1; printf ("Invalid-please read directions carefully\n"); } else if (slash != '/') { error = 1; printf ("Invalid-separate numerator and denominator"); printf (" by a slash (/)\n"); } else if (*denomp <= 0) { error = 1; printf ("Invalid-denominator must be positive\n"); } /* Discard extra input characters */ do { scanf ("%c", &discard); } while (discard != '\n'); } while (error); } /* Gets and returns a valid arithmetic operator. Skips over newline characters and permits re-entry of operator in case of error. */ char get_operator(void) { char op; printf("Enter an arithmetic operator (+,-,* or /)\n> "); for (scanf("%c", &op); op != '+' && op != '-' && op != '*' && op != '/'; scanf("%c", &op)) { if (op != '\n') printf("%c invalid, reenter operator (+,-,*,/)\n> ", op); } return (op); } /* Adds fractions from the input values */ void add_fractions (int n1, int d1, int n2, int d2, int *n_ansp, int *d_ansp) { int denom, numer, sign_factor; /* Finds a common deminator */ denom = d1 * d2; /* Computes numerator */ numer = n1 * d2 + n2 * d1; /* Adjusts sign (at most, numerator should be negative) */ if (numer * denom >= 0) sign_factor = 1; else sign_factor = -1; numer = sign_factor * abs(numer); denom = abs(denom); /* Returns result */ *n_ansp = numer; *d_ansp = denom; } /* multip[ly fractions represented by pairs of integers */ void multiply_fractions(int n1, int d1, int n2, int d2, int *n_ansp, int *d_ansp) { /* local variables */ int numer, denom; /* Computes numerator */ numer = n1 * n2; /* Computes denominator */ denom = d1 * d2; /* Display trace message */ printf("\nEnter multiply_fractions with\n"); printf("n1 = %d, d1 = %d, n2 = %d, d2 = %d\n", n1, d1, n2, d2); /* Returns result */ *n_ansp = numer; *d_ansp = denom; } /* Finds greatest common divisor of two integers */ int find_gcd (int n1, int n2) { int p, q, r, gcd; q = abs(n1); p = abs(n2); r = q%p; while (r != 0) { q = p; p = r; r = q%p; } gcd = p; /* Displays trace message */ printf ("\nEntering find_gcd with n1 = %d, n2 = %d\n", n1, n2); /* Display exit trace message */ printf ("The greatest common denominator is %d\n", gcd); return (gcd); } /* Reduces a fraction by dividing its numerator and denominator by their greatest common divider */ void reduce_fraction (int *nump, int *denomp) { int gcd; gcd = find_gcd (*nump, *denomp); *nump = *nump / gcd; *denomp = *denomp / gcd; } /* Displays pair of integers as a fraction */ void print_fraction (int num, int denom) { printf ("%d/%d", num, denom); }