I'm having great difficulty with the following that I need to do for an assign:
a. Declare a data structure that contains a rational number.
b. Write f'xns that will +, -, *, / rational numbers.
All f'xns have to pass 3 parameters, each pointing to a data structure of the type I declared in part a; 2 of the parameters = operands, 3rd = result.
c. Write a f'xn that takes a pointer to your data structure as a parameter and returns the GCD of the numer. & denom.
d. Use your f'xn from part c to write a f'xn that will reduce a fraction (rational number) to lowest terms. Pass in a pointer to the fraction and have the fraction modified by the f'xn.
e. Write input and output functions so that a user can enter a fraction in the form 1/5 for example.
The user should be allowed to enter any number of problems, and the program should output the answer in lowest terms.
Am I on the right track? I believe I have a-c down, but not d and especially e. Can someone please guide me or help me correct my script?
int GCD (int numer, int denom)
{
int result;
while (denom > 0) {
result = numer % denom;
numer = denom;
denom = result;
}
return numer;
}
int getLCM (int numer, int denom)
{
int max;
max = (numer > denom) ? numer : denom;
while (1) {
if (max % numer == 0 && max % denom == 0)
break;
++max;
}
return max;
}
struct Fraction
{
int numer;
int denom;
};
typedef struct
{
int numer;
int denom;
};
Fraction
Fraction add_fractions (Fraction a, Fraction b)
{
Fraction sum;
sum.numer = (a.numer * b.denom) + (b.numer * a.denom);
sum.denom = a.denom * b.denom;
return sum;
}
Fraction subtract_fractions (Fraction a, Fraction b)
{
Fraction sum;
sum.numer = (a.numer * b.denom) - (b.numer * a.denom);
sum.denom = a.denom * b.denom;
return sum;
}
Fraction multiply_fractions (Fraction a, Fraction b)
{
Fraction sum;
sum.numer = (a.denom * b.denom);
sum.denom = (a.numer * b.numer);
return sum;
}
Fraction divide_fractions (Fraction a, Fraction b)
{
Fraction sum;
sum.numer = (a.denom * b.numer);
sum.denom = (a.numer * b.denom);
return sum;
}
int main ()
{
char response;
printf ("FRACTION ARITHMETIC PROGRAM\n");
printf ("Enter your problem (example 2/3 + 1/5):\n");
scanf (, &problem);
if (denom == 0 || denom < 0) {
printf ("Illegal input!!\n");
printf ("Another problem (y/n)? ");
scanf ("%c%*c", &response);
} else {
printf ("The answer is ");
printf ("Another problem (y/n)? ");
scanf ("%c%*c", &response);
}
while ((response == 'y') || (response == 'Y')) {
printf ("\nWould you like to play again?\n");
scanf ("%c%*c", &response);
}
while ((response == 'n') || (response == 'N'))
printf ("Goodbye and thank you");
return 0;
}
Edit after removing typedef thanks to comment responses:
struct Fraction {
int numer;
int denom;
};
struct Fraction add_fractions (struct Fraction a, struct Fraction b)
{
struct Fraction sum;
sum.numer = (a.numer * b.denom) + (b.numer * a.denom);
sum.denom = a.denom * b.denom;
return sum;
}
struct Fraction subtract_fractions (struct Fraction a, struct Fraction b)
{
struct Fraction sum;
sum.numer = (a.numer * b.denom) - (b.numer * a.denom);
sum.denom = a.denom * b.denom;
return sum;
}
struct Fraction multiply_fractions (struct Fraction a, struct Fraction b)
{
struct Fraction sum;
sum.numer = (a.denom * b.denom);
sum.denom = (a.numer * b.numer);
return sum;
}
struct Fraction divide_fractions (struct Fraction a, struct Fraction b)
{
struct Fraction sum;
sum.numer = (a.denom * b.numer);
sum.denom = (a.numer * b.denom);
return sum;
}
Some remarks with your code:
LCM(a,b) = a * b / GCD(a,b)
computed as lcm = (a/gcb) * b
to reduce overflow risk (thanks to @n.m. for the simplified form)"%d/%d"
format for both input and output, with the two members of a struct?Last but not least, format "%c%*c"
to get answer to a y/n question is possible but dangerous: you are likely to get the newline of preceding input into response! Choose one of line oriented input (with fgets
+ sscanf
) or free form input (with scanf
or fscanf
) and stick to it. %1s
into a char response[2]
is much safer...
And carefully write in comment that you only process positive rationals or take care of sign! Such a detail can make users of a library rather angry ... not to mention nitpicking teachers (credits for Jonathan Leffler).
You can use an enum for operators and a function to switch on the operators since all operators follow a similar pattern. This simplifies the code. Here is example of some of the implementations, you can add the rest:
typedef struct node {
int nom;
int denom;
} Tfraction;
typedef enum {PLUS, MINUS, MULTIPLY, DIVIDE} Ops;
int calculate(int x, Ops op, int y) {
switch (op) {
case PLUS: return x + y;
case MINUS: return x - y;
case MULTIPLY: return x * y;
case DIVIDE: return x / y;
}
}
//reccursive gcd
int gcdr (int a, int b) {
if (a == 0) return b;
return gcdr(b % a, a);
}
void simplify(Tfraction *fraction) {
int gcd = gcdr(fraction->nom, fraction->denom);
fraction->nom /= gcd;
fraction->denom /= gcd;
}
Tfraction compute(Tfraction a, Tfraction b, Ops op) {
if (op == DIVIDE) {
int temp = b.nom;
b.nom = b.denom;
b.denom = temp;
op = MULTIPLY;
}
if (op == MULTIPLY) {
Tfraction result = { calculate(a.nom, op, b.nom), calculate(a.denom, op, b.denom) };
simplify(&result);
return result;
}
if (a.denom == b.denom) {
Tfraction result = { calculate(a.nom, op, b.nom), a.denom };
simplify(&result);
return result;
}
else {
Tfraction result = { (calculate((a.nom * b.denom), op, (b.nom * a.denom))), (a.denom * b.denom) };
simplify(&result);
return result;
}
}
int main ()
{
//Test
Tfraction f1 = {2, 4}, f2 = {4, 2};
printf("Addition: %d/%d\n", compute(f1, f2, PLUS).nom, compute(f1, f2, PLUS).denom);
printf("Subtraction: %d/%d\n", compute(f1, f2, MINUS).nom, compute(f1, f2, MINUS).denom);
printf("Multiplication: %d/%d\n", compute(f1, f2, MULTIPLY).nom, compute(f1, f2, MULTIPLY).denom);
printf("Division: %d/%d\n", compute(f1, f2, DIVIDE).nom, compute(f1, f2, DIVIDE).denom);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With