user1882972
user1882972

Reputation:

How to add two fractions?

Assuming that these functions are already given:

include <stdio.h>     /* printf                         */
include "fractions.h" /* struct FRACTION, add_fractions */

struct FRACTION make_fraction(int numerator, int denominator)
{
  struct FRACTION f;

  f.numerator = numerator;
  f.denominator = denominator;

  return f;
}

void test_fraction(int numerator1, int denominator1, 
                   int numerator2, int denominator2)
{
  struct FRACTION a = make_fraction(numerator1, denominator1);
  struct FRACTION b = make_fraction(numerator2, denominator2);

  struct FRACTION c = add_fractions(&a, &b);

  printf("%i/%i + %i/%i = %i/%i\n", a.numerator, a.denominator,
                                    b.numerator, b.denominator,
                                    c.numerator, c.denominator);
}

void testGCD(void)
{
  int m, n;

  m = 15; n = 18; /* GCD is 3 */
  printf("GCD of %i and %i is %i\n", m, n, GCD(m, n));
  printf("GCD of %i and %i is %i\n", n, m, GCD(n, m));

  m = 80; n = 20; /* GCD is 20 */
  printf("GCD of %i and %i is %i\n", m, n, GCD(m, n));
  printf("GCD of %i and %i is %i\n", n, m, GCD(n, m));

  m = 21; n = 47; /* GCD is 1 */
  printf("GCD of %i and %i is %i\n", m, n, GCD(m, n));
  printf("GCD of %i and %i is %i\n", n, m, GCD(n, m));

  m = 68; n = 153; /* GCD is 17 */
  printf("GCD of %i and %i is %i\n", m, n, GCD(m, n));
  printf("GCD of %i and %i is %i\n", n, m, GCD(n, m));
}

int main(void)
{
  testGCD();

  test_fraction(2, 3, 1, 6);
  test_fraction(1, 5, 4, 9);
  test_fraction(3, 7, 12, 21);
  test_fraction(5, 8, 3, 16);
  test_fraction(7, 8, 3, 12);
  test_fraction(0, 8, 3, 16);
  test_fraction(1, 1, 3, 16);
  test_fraction(5, 8, -3, 16);
  test_fraction(1, 5, -4, 9);
  test_fraction(-1, 5, -4, 9);


  return 0;
}

My task is to write GCD() and add_fractions(), and this is what I have written:

include "fractions.h" 

struct FRACTION add_fractions(const struct FRACTION *a, const struct FRACTION *b)
{                                    
    struct FRACTION c ; /*result struct*/
   /* int GCD_a = GCD(a.numerator, a.denominator);  GCD of the fraction a*/ 
    /*int GCD_b = GCD(b.numerator, b.denominator);  GCD of the fraction b*/

    c.numerator = (a.numerator) + (b.numerator);
    c.denominator = a.denominator ;


    return c;
  /* struct FRACTION empty;*/
   /*return empty;*/
}

int GCD(int a, int b)
{
    /*Variables*/
    int remainder = 0; /*remainder*/
    int larger = a;    
    int smaller = b;

    remainder = larger % smaller;
    while (remainder != 0)
    {
      larger = smaller;
      smaller = remainder;
      remainder = larger % smaller;
    }

    return smaller;
}

Assuming that for the moment both denominators are equals, why I can't run this with Cygwin? I use this command to compile

gcc -Wall -Wextra -ansi -pedantic -Wno-unused-parameters main.c fractions.c -o fractions.exe    

and I have two errors: (Cygwin is in Spanish on my computer so I am not sure that what I am going to write is the exact translation):

error: trying to put "numerator" in something which is not a struct

(and the same for denominator)

What is the problem?

Upvotes: 4

Views: 5691

Answers (3)

StuartLC
StuartLC

Reputation: 107327

In addition to user529758's point that your addition algorithm should be

  n1 * d2 + n2 * d1
= ------------------
       d1 * d2  

I believe Jonathan's point needs to be emphasized that you will then need to divide the numerator and denominator of the result through by the GCD to reduce the resulting fraction to its lowest form.

For example, you can implement a new function to do the reduction:

struct FRACTION reduce_fraction(const struct FRACTION *frac)
{
    struct FRACTION reduced;
    int gcd = GCD(frac->numerator, frac->denominator);

    reduced.numerator = frac->numerator / gcd;
    reduced.denominator = frac->denominator / gcd;

    return reduced;
}

Your add_fraction function will now look like this:

struct FRACTION add_fractions(const struct FRACTION *a, const struct FRACTION *b)
{                                    
    struct FRACTION c;

    c.numerator = (a->numerator * b->denominator) + (b->numerator * a->denominator);
    c.denominator = a->denominator * b->denominator;
    return reduce_fraction(&c);
}

Also, given that you've done the hard work in determining what the result should be in the comments, instead of printfing to stdout, why not assert these - this provides the basis for automated unit tests:

#include <assert.h>
...
m = 15; n = 18;
assert(GCD(m, n) == 3);
assert(GCD(m, n) == GCD(n,m));

m = 80; n = 20;
assert(GCD(m, n) == 20);
assert(GCD(m, n) == GCD(n,m));

And the same for add_fractions and reduce_fraction, as well :)

Upvotes: 1

user529758
user529758

Reputation:

const struct FRACTION *a, const struct FRACTION *b

So a and b are pointers to a constant struct FRACTION. Then later you write:

c.numerator = (a.numerator) + (b.numerator);

you don't access members of struct pointers using ., but using ->, this should be

c.numerator = a->numerator + b->numerator;

P. s. 1: the parentheses are not needed, don't put them in superfluously, they decrease readability.

P. s. 2: your addition formula is broken, use

c.numerator = a->numerator * b->denominator + b->numerator * a->denominator;
c.denominator = a->denominator * b->denominator;

instead.

Upvotes: 5

John Bode
John Bode

Reputation: 123558

In your add_fractions function, you've declared a and b as pointers to struct FRACTION:

struct FRACTION add_fractions(const struct FRACTION *a, const struct FRACTION *b)

Since a and b are pointers, not structs, you can't write things like a.numerator.

You either need to dereference a and b before using the . operator:

c.numerator = ((*a).numerator) + ((*b).numerator);
c.denominator = (*a).denominator ;

or use the -> component selection operator, which is a shorthand way of doing the same thing:

c.numerator = (a->numerator) + (b->numerator);
c.denominator = a->denominator ;

Upvotes: 1

Related Questions