# Coding the struct implementation of fraction

Besides the standard operation on fractions, we must also
consider that we can no longer print this type by giving a simple
print specifier, like %d or %c. It's just more complicated than that.
So we need to add a function that can print a fraction in a manner that
is standard.
It might be necessary for us to initialize a fraction to 0. So we'll
need an InitFraction() function.

We would also like to provide a function that allows us to assign some
value to a fraction. So we should write this as well.

These three functions are probably the first that should be written.

/************************************************\
* Filename: fraction.c *
* Author: Sue Bogar *
* Date Written: 4/15/98 *
* Modified: 11/20/05 *
* Section: 01XX & 02XX *
* EMail: bogar@cs.umbc.edu *
* *
* Description: This file contains the functions *
* necessary to work with the structure *
* implementation of the fraction ADT defined in *
* in fraction.h. This set of functions provide *
* the operations needed to work with this type, *
* and include initialization, assignment, and *
* printing of fractions. The standard aritmetic *
* operations on fractions and some supporting *
* functions, for finding the greatest common *
* divisor of two integers and a function for *
* reducing fractions to lowest terms. *
\************************************************/
#include
#include "fraction.h"
/************************************************
** Function: AddFractions
** Input: fPtr1 and fPtr2 are FRACTPTRs to the fractions
** to be added
** Output: nothing is returned
**
** This function modifies the FRACTION sum in the calling function
** which is passed by reference. It will hold the sum of the two
** FRACTIONS which were also passed by reference using the pointers
** fPtr1 and fPtr2. The sum has been reduced to lowest terms.
*******************************************/
void AddFractions (FRACTPTR fPtr1, FRACTPTR fPtr2, FRACTPTR sumPtr)
{
sumPtr->whole = fPtr1->whole + fPtr2->whole;
sumPtr->denominator = fPtr1->denominator * fPtr2->denominator;
sumPtr->numerator = fPtr1->denominator * fPtr2->numerator
+ fPtr2->denominator * fPtr1->numerator;
RedToLowTerms(sumPtr);
}
/***********************************************
** Function: SubFractions
** Input: fPtr1 and fPtr2 are FRACTPTRs to the fractions
** to be subtracted (f1 -f2)
** Output: nothing is returned
**
** This function modifies the FRACTION difference in the calling function
** which is passed by reference. It will hold the difference (f1 - f2) of
** the two FRACTIONS which were also passed by reference using the pointers
** fPtr1 and fPtr2. The difference has been reduced to lowest terms.
**************************************/
void SubFractions (FRACTPTR fPtr1, FRACTPTR fPtr2, FRACTPTR differencePtr)
{
differencePtr->whole = fPtr1->whole - fPtr2->whole;
differencePtr->denominator = fPtr1->denominator * fPtr2->denominator;
differencePtr->numerator = fPtr2->denominator * fPtr1->numerator
- fPtr1->denominator * fPtr2->numerator ;
RedToLowTerms(differencePtr);
}
/**************************************
** Function: MultFractions
** Input: fPtr1 and fPtr2 are FRACTPTRs to the fractions
** to be multiplied
** Output: nothing is returned
**
** This function modifies the FRACTION product in the calling function
** which is passed by reference. It will hold the product of the two
** FRACTIONS which were also passed by reference using the pointers
** fPtr1 and fPtr2. The product has been reduced to lowest terms.
**************************************/
void MultFractions (FRACTPTR fPtr1, FRACTPTR fPtr2, FRACTPTR productPtr)
{
fPtr1->numerator = fPtr1->denominator * fPtr1->whole + fPtr1->numerator;
fPtr1->whole = 0;
fPtr2->numerator = fPtr2->denominator * fPtr2->whole + fPtr2->numerator;
fPtr2->whole = 0;
productPtr->whole = 0;
productPtr->numerator = fPtr1->numerator * fPtr2->numerator;
productPtr->denominator = fPtr1->denominator * fPtr2->denominator;
RedToLowTerms(productPtr);
}
/**************************************
** Function: DivFractions
** Input: fPtr1 and fPtr2 are FRACTPTRs to the fractions
** to be divided (f1 / f2)
** Output: nothing is returned
**
** This function modifies the FRACTION quotient in the calling function
** which is passed by reference. It will hold the quotient (f1 / f2) of
** the two FRACTIONS which were also passed by reference using the pointers
** fPtr1 and fPtr2. The quotient has been reduced to lowest terms.
** DivFractions inverts the fraction f2 and then calls MultFractions()
**
** CAVEAT: This function assumes that the value of f2 is not 0
**************************************/
void DivFractions (FRACTPTR fPtr1, FRACTPTR fPtr2, FRACTPTR quotientPtr)
{
FRACTION inverted;
int numer, denom;
numer = fPtr2->whole * fPtr2->denominator + fPtr2->numerator;
denom = fPtr2->denominator;
inverted.whole = 0;
inverted.numerator = denom;
inverted.denominator = numer;
MultFractions(fPtr1, &inverted, quotientPtr);
}
/**************************************
** Function: RedToLowTerms
** Input: a pointer to a FRACTION
** Output: there is no return value
** the FRACTION being pointed to is reduced
** to lowest terms
**
** RedToLowTerms takes one argument of type FRACTPTR
** and reduces that fraction to lowest terms by finding
** the greatest common divisor of the numerator and
** denominator and dividing through by that value.
**************************************/
void RedToLowTerms (FRACTPTR fPtr)
{
int gcd, numer, denom;
denom = fPtr->denominator;
numer = fPtr->whole * denom + fPtr->numerator;
gcd = GCD (numer, denom);
numer /= gcd;
denom /= gcd;
fPtr->whole = numer/denom;
fPtr->numerator = numer % denom;
fPtr->denominator = denom;
}
/**************************************
** Function: InitFraction
** Input: a pointer to a FRACTION
** Output: the FRACTION pointed to is initialized
** whole = num = 0
** denominator = 1
**
** Note:
** denominator is set to 1 because division
** by 0 is undefined.
**************************************/
void InitFraction (FRACTPTR fPtr)
{
fPtr->whole = 0;
fPtr->numerator = 0;
fPtr->denominator = 1;
}
/**************************************
* Function: AssignFraction
* Input: a pointer to a FRACTION
* an integer whole part
* an integer numerator
* an integer denominator
* Output: the corresponding members of the FRACTION
* are initialized to the whole,numerator &
* denominator provided by the caller
**************************************/
void AssignFraction (FRACTPTR fPtr, int whole, int num, int denom)
{
fPtr->whole = whole;
fPtr->numerator = num;
fPtr->denominator = denom;
}
/**************************************
* Function: PrintFraction
* Input: a FRACTION, f
* Ouput: f is printed according to the format
* specified within this code
* Example: 1 1/4
* there is no return value
*
**************************************/
void PrintFraction (FRACTPTR fPtr)
{
printf("%d %d/%d", fPtr->whole, fPtr->numerator,
fPtr->denominator);
}
/**************************************
* Function: GCD (Greatest Common Divisor)
* Input: two integers
* Output: the greatest common divisor
* of the integers
* Description:
* GCD takes two integer arguments and
* calculates the greatest common divisor of
* those numbers using Euclid's GCD algorithm.
**************************************/
int GCD (int a, int b)
{
int remainder;
remainder = a % b;
while (remainder != 0)
{
a = b;
b = remainder;
remainder = a % b;
}
return b;
}
Here is the driver that I used to test the functions as I wrote them.
I just kept adding more and more to the main as I continued to write the
functions one by one.

/*********************************************
** File: testFrac.c
** Author: S. Bogar
** Date: 4/16/98
** Modified: 11/20/05
** Section: 01XX & 02XX
** EMail: bogar@cs.umbc.edu
**
** Driver to test fractions
*********************************************/
#include
#include "fraction.h"
int main ()
{
int whole, num, denom;
FRACTION f1, f2, answer;
/* Get two fractions from the user */
/* Fraction 1 */
printf("Enter first fraction:\n");
printf("Enter whole number: ");
scanf("%d", &whole);
printf("Enter numerator: ");
scanf("%d", &num);
printf("Enter denominator: ");
scanf("%d", &denom);
AssignFraction(&f1, whole, num, denom);
/* Fraction 2 */
printf("Enter second fraction:\n");
printf("Enter whole number: ");
scanf("%d", &whole);
printf("Enter numerator: ");
scanf("%d", &num);
printf("Enter denominator: ");
scanf("%d", &denom);
AssignFraction(&f2, whole, num, denom);
/* Print the fractions */
printf("f1 = ");
PrintFraction(&f1);
printf ("\n");
printf("f2 = ");
PrintFraction(&f2);
printf ("\n\n");
/* Test addition */
AddFractions(&f1, &f2, &answer);
printf("answer to addition = ");
PrintFraction(&answer);
printf ("\n");
/* Test subtraction */
SubFractions(&f1, &f2, &answer);
printf("answer to subtraction = ");
PrintFraction(&answer);
printf ("\n");
/* Test multiplication */
MultFractions(&f1, &f2, &answer);
printf("answer to multiplication = ");
PrintFraction(&answer);
printf ("\n");
/* Test division */
DivFractions(&f1, &f2, &answer);
printf("answer to division = ");
PrintFraction(&answer);
printf ("\n");
return 0;
}
## Output

Enter first fraction:
Enter whole number: 3
Enter numerator: 1
Enter denominator: 2
Enter second fraction:
Enter whole number: 1
Enter numerator: 2
Enter denominator: 3
f1 = 3 1/2
f2 = 1 2/3
answer to addition = 5 1/6
answer to subtraction = 1 5/6
answer to multiplication = 5 5/6
answer to division = 2 1/10