Practice Assignment

(fractions.c)

Information

Please read ALL of the information before writing any code. Most of the problems that student's have are a result of writing code without reading the instructions.

In this practice, you will write functions that will add, subtract, multiply, and reduce fractions.
  1. In the first part of the practice, you will write a GCD (Greatest Common Divisor) function. I showed the code during the first lectures on Fundamentals at the bottom of the notes. After implementing the GCD function, run the tests from the driver to make sure you've implemented it correctly before using it with the fractions in the later parts of the practice.

    The prototype for the GCD function looks like this:

    int GCD(int a, int b);
    

    The GCD is meant for positive integers. However, you may have 0 and negative numbers when manipulating the fractions. So, for this practice you will need to modify the GCD function to deal with that situation. For example, if X is an integer, then:

    Some examples:

    GCD of 15 and 18 is 3
    GCD of 21 and 47 is 1
    GCD of 153 and 68 is 17
    GCD of 18 and 0 is 18
    
    The function requires about 15 lines of code.


  2. In the second part of the practice you will write functions that will add, subtract, multiply, and reduce fractions. The trick is that you are not going to convert the fraction into a decimal number, but you are going to leave the result in fractional form. This means that all results will have a numerator and a denominator. Some examples:
     1     1     1         2     1     5         1     4     29         1     -4    -11                                                     
    --- + --- = ---       --- + --- = ---       --- + --- = ----       --- + ---- = ----                                                                                        
     6     6     3         3     6     6         5     9     45         5     9      45                                                 
    
    You'll notice that the fractions are all reduced to lowest terms.

    This is the general form for adding two fractions:

     A     C       AD     BC       AD + BC            
    --- + ---  =  ---- + ----  =  ---------
     B     D       BD     BD          BD        
    
    Example:
     2     1       2 * 6     1 * 3       12      3       12 + 3       15       5
    --- + ---  =  ------- + -------  =  ---- + ----  =  --------  =  ----  =  ---    
     3     6       3 * 6     3 * 6       18     18         18         18       6
    
    Multiplying is even easier:
     A     C       AC
    --- * ---  =  ----
     B     D       BD 
    
    Example:
     2     1       2 * 1      2       1
    --- * ---  =  ------- + ----  =  ---
     3     6       3 * 6     18       9
    
    To practice with structures, we're going to create a structure called FRACTION which we'll use to represent a fraction:
    struct FRACTION
    {
      int numerator;
      int denominator;
    };
    
    You'll need to write 3 functions that all take two FRACTION pointers and return a new FRACTION:
    (18)  struct FRACTION add_fractions(const struct FRACTION *a, const struct FRACTION *b);
    ( 3)  struct FRACTION subtract_fractions(const struct FRACTION *a, const struct FRACTION *b);
    ( 8)  struct FRACTION multiply_fractions(const struct FRACTION *a, const struct FRACTION *b);
    
    The numbers to the left in parentheses represent the approximate number of lines required for each function.
    To put the fraction in lowest terms, you need to divide the numerator and denominator by their Greatest Common Factor, GCD. This is the function you wrote in the first part of the practice.

    So, revisiting the example above, the GCD of 15 and 18 is 3, so we divided the numerator and denominator by 3:

     2     1       2 * 6     1 * 3       12      3       12 + 3       15       15/3       5
    --- + ---  =  ------- + -------  =  ---- + ----  =  --------  =  ----  =  ------  =  ---    
     3     6       3 * 6     3 * 6       18     18         18         18       18/3       6
    

    Hint: Subtracting two fractions is very similar to adding them. In fact, subtraction in general is very similar to addition. For example, a - b can be re-written as addition simply by negating b: a + -b. This means your subtract_fractions function should call your add_fractions function. This is code re-use. Writing two full add/subtract functions is the wrong way to do it. Don't be wrong. Be right.


  3. The third part of the practice you will convert an improper fraction into a mixed fraction:
     52         20         5
    ----  =  1 ----  =  1 ---    
     32         32         8
    
    For example, the entire process looks like this:
     3     7       3 * 8     4 * 7       24     28       24 + 28       52       13         5
    --- + ---  =  ------- + -------  =  ---- + ----  =  ---------  =  ----  =  ----  =  1 ----
     4     8       4 * 8     4 * 8       32     32         32          32        8         8
    
    This is the prototype for the function to do this:
    struct MIXED_FRACTION reduced_to_mixed(const struct FRACTION *fraction);
    
    Because a mixed fraction can have a whole number and a proper fraction, we need another structure to support this:
    struct MIXED_FRACTION
    {
      int whole_number;
      struct FRACTION proper_fraction;
    };
    
    So, given a MIXED_FRACTION named mixed for this fraction:
       5
    1 ---
       8
    
    The fields are:
    mixed.whole_number is 1
    mixed.proper_fraction.numerator is 5
    mixed.proper_fraction.denominator is 8
    
    This function also "fixes" these "problems" as well:
    1/1 ==> 1
    0/1 ==> 0
    

    Look at the test_fraction function in the driver and the output files to see how you should represent 0.

    The function requires about 20 lines of code.


More details