C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
Get inside! Sample the range of functionality easily built with JMSL Library for Time Series Data Analysis, Heat Maps, Portfolio Optimization, Monte Carlo Simulation, Stock Price Charting and more. Download Now!
  #1  
Old October 5th, 2002, 11:27 AM
Rdesign Rdesign is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2002
Location: Redding
Posts: 49 Rdesign User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
Fractions (int/int) question...

Greetings, I wrote a calculator program for fractions in this format:

a/b(+|-|*|/)c/d

It works fine all except for reduction. I would really love to reduce the final fraction...But I cannot think of a way to go about doing it. I have thought that the key might be in dividing both the numerator and the denomanator of the final fraction with the lowest denomanator of the first two fractions. I want everyone who reads this to understand that it isn't nessary to reduce the fraction to get full credit for the program, I just think it would be exciting to see if this can be done.

Thank-you to anyone who has the time to think about this. My source code is:


# include "iostream.h"
/*
*
* C++ Programming
* Problem 12 Chapter 5
* by Quinn Peters
*
* Fraction adding problem using
* functions.
*
*/

// The structure fraction, which init's
// the varables for use. Declared long because
// multiplication is a factor.
struct fraction {
long numer;
long denom;
};

// This is the fraction adding function
// all returning the fraction structure.
fraction fadd (fraction a, fraction b) {
fraction c = {0,0};
c.numer = (a.numer*b.denom) + (a.denom*b.numer);
c.denom = (a.denom*b.denom);
return c;
};

// The subtraction function.
fraction fsub (fraction a, fraction b) {
fraction c = {0,0};
c.numer = (a.numer*b.denom) - (a.denom*b.numer);
c.denom = (a.denom*b.denom);
return c;
};

// The multiplication function.
fraction fmul (fraction a, fraction b) {
fraction c = {0,0};
c.numer = (a.numer*b.numer);
c.denom = (a.denom*b.denom);
return c;
};

// The division function.
fraction fdiv (fraction a, fraction b) {
fraction c = {0,0};
c.numer = (a.numer*b.denom);
c.denom = (a.denom*b.numer);
return c;
};

// The main function, putting it all together,
// deciding which function will be used and
// gathering user input.
int main() {
char vchar, opera, again;
fraction first = {0,0};
fraction secon = {0,0};
fraction third = {0,0};
cout << "Fraction Calculator!" << '\n'
<< "Format is in: a/b(+|-|*|/)c/d"
<< '\n' << '\n';
do {
cout << '\n' <<"Fractions: ";
cin >> first.numer >> vchar
>> first.denom >> opera // The decicive operator. This controls the functions.
>> secon.numer >> vchar
>> secon.denom;
switch (opera) {
case '+': third = fadd(first, secon); break;
case '-': third = fsub(first, secon); break;
case '*': third = fmul(first, secon); break;
case '/': third = fdiv(first, secon); break;
}

// Print the final output to the screen
// and decide if the user wishes to repeat the
// process.
cout << '\n' << "Your answer: "
<< third.numer << "/" << third.denom
<< '\n' << '\n'
<< "Would you like to do this again? (y|n)" << '\n' << ">> ";
cin >> again;
} while (again == 'y');
return 0;
}

Reply With Quote
  #2  
Old October 5th, 2002, 01:53 PM
MJEggertson MJEggertson is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jan 2002
Location: Seattle WA
Posts: 863 MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 22 sec
Reputation Power: 8
It's been a long time since I've been in a mathematics class, but reducing a fraction means taking something like 6/8 and making it 3/4, right?

If that's so, then mathematically the most robust approach (though not necessarily the fastest) would be to first, create a prime number generator. Then, generate an array of prime numbers that are less than the denominator. Take note of which prime numbers give a modulus of zero when operated on the numerator, and a nother list of which generate a modulus of zero for the denominator.

For any prime number that exists in both lists, divide the numerator and denominator by said number.

Your fraction has been reduced.

That's the mathematics of it. Implementing it may be a bit of a problem. It would be easier if you could find a prime number generator, otherwise, it may be easiest just to hard-code a list up to whatever limits you want. An example of the mathematical logistics would be, using half-C notation:
Code:
unsigned long primes[]; // holds the prime numbers.
int length_of_primes; // holds the max index of primes[]

// ...

for (int i = 0; i < length_of_primes; i++)
{
    if (((c.denom % primes[i]) == 0)
        && ((c.number % primes[i]) == 0))
    {
        c.number /= primes[i];
        c.denom /= primes[i];
    }
}

So, you'd have a bit of work to do. GetPrimes should not return 0 in the array for obvious reasons. Returning 1 in the array for this implementation would be moot as well.

Reply With Quote
  #3  
Old October 5th, 2002, 09:58 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,442 Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 1 Month 1 h 55 m 33 sec
Reputation Power: 797
You can also try to compute the highest common factor (HCF) between two numbers (also sometimes called GCD - Greatest Common Divisor). Don't ask me why, but I still remember working out HCF problems in 5th grade, for some strange reason. The method we used was pretty straight forward. Let's say you had two numbers. Call the smaller one the divisor and the larger one the dividee.

1. Compute the reminder of dividee / divisor
2. If reminder is 0, go to step 5
3. Set dividee = divisor, divisor = reminder
4. Go to step 1
5. divisor is the highest common factor between the numbers

The nifty part about this method is that it doesn't require precomputing prime numbers at all. Now that you can compute the HCF of two numbers, you divide them both by the HCF and repeat the process, until your HCF is 1. Then, the final values of the two numbers will be the reduced fraction. Now for some actual code:
Code:
#include <stdio.h>

int hcf(int a, int b);
int reduce(int x, int y);

int main(void) {
  int x = 14, y = 21;
  reduce (x, y);
  return 0;
}

int reduce(int x, int y) {
  int divisor;
  int num1 = x, num2 = y;
  
  /* Keep reducing the numbers while the Highest Common
     Factor is > 1*/
  while ( (divisor = hcf(num1, num2)) > 1) {
    num1 /= divisor;
    num2 /= divisor;
  }

  printf("The fraction %d / %d can be reduced to %d / %d\n", x, y, num1, num2);
  return 0;
}

int hcf(int a, int b) {
  int num1, num2;
  int reminder;

  /* First make sure num1 is the greater of a and b 
     and num1 is the smaller number */
  num1 = (a >= b ? a : b);
  num2 = (a <= b ? a : b);

  if (num1 == 0 || num2 == 0)
    return 0;

  /* Now compute the Highest Common Factor (HCF) */
  while ( (reminder = (num1 % num2)) != 0) {
    num1 = num2;
    num2 = reminder;
  }

  return num2;
}

Hope this helps!

Last edited by Scorpions4ever : October 5th, 2002 at 10:21 PM.

Reply With Quote
  #4  
Old October 6th, 2002, 07:42 PM
Rdesign Rdesign is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2002
Location: Redding
Posts: 49 Rdesign User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
Thanks!

Wow! Great thinking. I'll try both meathods and write again to keep you guys updated....

20 min. later...

I opted for choice #2, It works Great! I love that. Such a thing, I couldn't think of a way around that. You are all amazing and I appricate your help. Thanks-again. The new code:


ps: Would it be OK if I turned this problem in if I gave you credit for the reduction part in the code Scorpions4ever? I think my instructor would like to see the modified program.

# include "iostream.h"
/*
*
* C++ Programming
* Problem 12 Chapter 5
* by Quinn Peters
*
* Fraction adding problem using
* functions.
*
*/

// The structure fraction, which init's
// the varables for use. Declared long because
// multiplication is a factor.
struct fraction {
long numer;
long denom;
};

// This is the fraction adding function
// all returning the fraction structure.
fraction fadd (fraction a, fraction b) {
fraction c = {0,0};
c.numer = (a.numer*b.denom) + (a.denom*b.numer);
c.denom = (a.denom*b.denom);
return c;
};

// The subtraction function.
fraction fsub (fraction a, fraction b) {
fraction c = {0,0};
c.numer = (a.numer*b.denom) - (a.denom*b.numer);
c.denom = (a.denom*b.denom);
return c;
};

// The multiplication function.
fraction fmul (fraction a, fraction b) {
fraction c = {0,0};
c.numer = (a.numer*b.numer);
c.denom = (a.denom*b.denom);
return c;
};

// The division function.
fraction fdiv (fraction a, fraction b) {
fraction c = {0,0};
c.numer = (a.numer*b.denom);
c.denom = (a.denom*b.numer);
return c;
};

////////////////////////////////////////////////////////////////////
// Reduce the fraction!
// Code by: Scorpions4ever on Oct, 6 2002.
int hcf(long a, long b) {
int num1, num2, reminder;

// First make sure num1 is the greater of a and b
// and num1 is the smaller number
num1 = (a >= b ? a : b);
num2 = (a <= b ? a : b);

if (num1 == 0 || num2 == 0) {
return 0;
}
// Now compute the Highest Common Factor (HCF)
while ( (reminder = (num1 % num2)) != 0) {
num1 = num2;
num2 = reminder;
}
return num2;
};

void reduce(long x, long y) {
int divisor;
int num1 = x, num2 = y;

// Keep reducing the numbers while the Highest Common
// Factor is > 1*/
while ( (divisor = hcf(num1, num2)) > 1) {
num1 /= divisor;
num2 /= divisor;
}
// Print the final output to the screen.
cout << '\n' << "Your answer: "
<< num1 << "/" << num2
<< '\n' << '\n'
<< "Would you like to do this again? (y|n)" << '\n' << ">> ";

};
// end fraction reduction.
////////////////////////////////////////////////////////////////////

// The main function, putting it all together,
// deciding which function will be used and
// gathering user input.
int main() {
char vchar, opera, again;
fraction first = {0,0};
fraction secon = {0,0};
fraction third = {0,0};
cout << "Fraction Calculator!" << '\n'
<< "Format is in: a/b(+|-|*|/)c/d"
<< '\n' << '\n';
do {
cout << '\n' <<"Fractions: ";
cin >> first.numer >> vchar
>> first.denom >> opera // The decicive operator. This controls the functions.
>> secon.numer >> vchar
>> secon.denom;
switch (opera) {
case '+': third = fadd(first, secon); break;
case '-': third = fsub(first, secon); break;
case '*': third = fmul(first, secon); break;
case '/': third = fdiv(first, secon); break;
}
// decide if the user wishes to repeat the process.
reduce(third.numer, third.denom);
cin >> again;
} while (again == 'y');
return 0;
}

Last edited by Rdesign : October 6th, 2002 at 08:24 PM.

Reply With Quote
  #5  
Old October 6th, 2002, 10:08 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,442 Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 1 Month 1 h 55 m 33 sec
Reputation Power: 797
Hehe you can give me credits if you like (or take all the credits... I don't mind ). BTW I made a typo in my comments above and you have the same error in your code as well:

// First make sure num1 is the greater of a and b
// and num1 is the smaller number

should be

// First make sure num1 is the greater of a and b
// and num2 is the smaller number

Also you've accidentally included part of my c-style comments in your code:
// Keep reducing the numbers while the Highest Common
// Factor is > 1*/

You might want to fix these before turning your code in

[edit] Also noticed that you're passing long params into the two functions, but assigning them to int variables. You might want to change the declarations of all the variables to long in those two functions[/edit]

Last edited by Scorpions4ever : October 6th, 2002 at 10:11 PM.

Reply With Quote
  #6  
Old October 6th, 2002, 10:31 PM
Rdesign Rdesign is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2002
Location: Redding
Posts: 49 Rdesign User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 6
It worked tho..

um...I'll fix all those things. I was excited that it worked with so few errors. Fraction-type calculator that rounded even impressed my wife (who usually doesn't care). Cool of you to point that stuff out though. Thanks again.

Quinn

Last edited by Rdesign : October 6th, 2002 at 10:36 PM.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > Fractions (int/int) question...


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway