Reputation:
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
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 printf
ing 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
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
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