Overloading operator + for fractions (using lcm) - c++

I want to compute the sum of two fraction using lcm of numerator and denominator. That means as a result I want to get a fraction in the reduced form. I have the following cpp file.
#include <iostream> //need it for cin and cout
#include "fraction.h"
Fraction::Fraction()
{
num = 1;
den = 1;
}
Fraction::Fraction(int n, int d)
{
int tmp_gcd = gcd(n, d);
num = n / tmp_gcd;
den = d / tmp_gcd;
}
int Fraction::gcd(int a, int b)
{
int tmp_gcd = 1;
// Implement GCD of two numbers;
return tmp_gcd;
}
int Fraction::lcm(int a, int b)
{
return a * b / gcd(a, b);
}
Fraction operator+(const Fraction&a,const Fraction &b)
{
int c=(lcm(b.den,a.den)/b.den)*a.num+b.num*(lcm(b.den,a.den)/a.den);
int d=lcm(b.den,a.den);
Fraction result(c,d);
return result;
}
However this code does not work because lcm is not defined in this scope.
What is the key that allows lcm work in this scope? If you please could explain more, I would be very thankful.

lcm is a member of Fraction. You can refer to it just as lcm within members of Fraction; but operator+ isn't a member, so you'll have to use the qualified name Fraction::lcm.
It will also need to be static. (Hopefully it already is, but I can't see the declaration to be sure).

Related

how to overload minus operator to subtract two fractional numbers?

I want to subtract two fractional numbers using operator overloading. I have write a piece of code in order to accomplish this task:
#include<iostream>
using namespace std;
void HCF(int& a, int& b)
{
int m, n;
m = a;
n = b;
while (m != n)
{
if (m > n)
m = m - n;
else
n = n - m;
}
a = a / m;
b = b / m;
}
class Rational {
int x1;
int y1;
public:
void simplify()
{
int m, n, r;
n = fabs(y1);
m = fabs(x1);
while (r = m % n)//Find the Maximum Common Number of m,n
{
m = n;
n = r;
}
y1 /= n; // Simplification
x1 /= n;
if (y1 < 0) // Convert denominator to positive number
{
y1 = -y1;
x1 = -x1;
}
}
Rational(int num = 0, int denom = 1)
{
if (denom) {
x1 = num;
y1 = denom;
}
else {
x1 = 0;
y1 = 1;
}
}
Rational(const Rational& copy)//Copy Constructor
{
x1 = copy.x1;
y1 = copy.y1;
}
Rational operator-(const Rational& x) const //Overloaded minus operator
{
Rational temp;
temp.x1 = x1 * x.y1 - x.x1 * y1;
temp.y1 = y1 * x.y1;
temp.simplify();
return temp;
}
operator string() const //Overloaded string operator
{
int numerator = x1, denominator = y1;
HCF(numerator, denominator);
string str;
if (denominator == 1)
str = to_string(numerator);
else
str = to_string(numerator) + "/" + to_string(denominator);
return str;
}
};
int main()
{
Rational a(5, 1);
Rational b(3, 4);
Rational c;
Rational d;
Rational x(5, 1);
c = a - x;
string expected1 = "0"; //Expected value
string actual1 = (string)c;//Actual value
cout << actual1.compare(expected1);//Comparing actual and expected value
d = c - b;
string expected2 = "-3/4";
string actual2 = (string)d;
cout << actual2.compare(expected2);
}
As we can see, in the main() function, both cout statements should print 0 because when we compare both strings, they must be equal. But the problem is, when I run this program, it prints nothing, and I don't know why.
My operator string() converts an integer fraction into a string. My operator- takes the LCM and finds the final value after subtracting two fractional numbers. In the main() function, I have declared five objects for class Rational, and then I simply perform subtraction and then I compare the expected and actual values, which should return 0 in the cout statement.
I have also used the simplify() member function to check whether the fraction is completely in simpler form or not. For example, it should simplify 2/4 into 1/2.
Where is the mistake? All other functions except operator- are running correctly. The real problem is with the operator-, ie when we perform c=a-x, the value of c would be 0 as a string. Similarly, if we perform d=c-b then the expected value should be -3/4 as a string.
I have also tried to run this code on Google Test, but it fails the test case.
Use this GCD (greatest common divisor) function to implement your HCF function. Yours currently exhibits an endless loop when given 0 as a first argument.
To reduce a fraction, divide numerator and denominator by their greatest common divisor.
This is called the Euclidean algorithm.
template <typename T>
T GCD(T a, T b) {
while (b != 0)
{
T t = a % b;
a = b;
b = t;
}
return std::max(a, -a);
}

How do I create a fraction class with two friend functions in c++

I have an assignment that requires alot of use with classes, the idea of the code is to manipulate fractions to find greatest common denominator (GCD) and other things.
What I need (I know this is long):
Create a Fraction class with 2 private member variables numerator and denominator....one constructor with 2 integer parameters num and den with default values 0 and 1......one display function that prints out a fraction in the format numerator/denominator in the proper form such as 2/3 or 1/2. (2/4 for example should be displayed as 1/2)
HINTS FROM PROFESSOR:
Add a public membeer function called void proper().... that sets numerator and denomonator to the proper form by dividing both by the GCD(greatest common denominator) of them (example... you declare 12/18... after calling proper()...it becomes 2/3 (as the GCD of these is 6)
use public member function GCD() to get the greatest common denominator of the numerator and demoniator...(example 2/4... GCD() returns 2....for 12/18...GCD() returns 6).
[b]Code provided for GCD()
int GCD()
{
int gcd = 0;
int r=0;
u = numerator;
v = denominator;
while (true) {
if (v==0){
gcd = u;
break;
}
else {
r = u%v;
u =v;
v=r;
}
}
return gcd;
}
THEN
Create 2 functions as FRIEND functions of class fraction.
The first one called "sum" takes 2 fraction objects as parameters, it returns a fraction object with the result of the sum of the 2 fraction objects.(example... suppose a=1/4...b=1/2... the result of sum(a,b) should be 3/4.
The second one called "compare"...takes 2 fraction objects as parameters.... it returns 1 if the 2 are equal... and 0 if not. (example....a=1/2...b=2/4.. the result of compare(a,b) is 1)
Write main function to declare fraction objects and demonstrate a working code.
[/b]
So thats what im looking at... here is what I have so far... I know its not very much...
#include <iostream>
using namespace std;
class fraction
{
void friend sum();
void friend compare ();
private:
int numerator;
int denominator;
public:
fraction(int num = 0, int den = 1);
int GCD();
void proper();
void fraction::proper()
{
}
int GCD()
{
int gcd = 0;
int r=0;
u = numerator;
v = denominator;
while (true) {
if (v==0){
gcd = u;
}
else {
r = u%v;
u =v;
}
}
return gcd;
}
void sum()
{
}
void compare()
{
}
void main()
{
}
I am VERY confused about how to set this up with a "1/2" type input... im use to simple inputs like 1 or 2. If someone could help fill in the gaps a bit I would appreciate it... (keep in mind Im a beginner..)... this is my first time working with anything like this and I am in way over my head
Thank you!

Trying to calculate GCD in C++

I think I am not calling the function or passing it correctly. Here are a couple of snippets that I am having issues with.
Using test data, 1/2 and 8/16 returns 1/2 instead of 1/1.
This is my code to calculate the GCD:
void Fractions::gcd(int n, int d)
{
int a,b,c;
a = n;
b = d;
while (a%b != 0)
{
c = a % b;
a = b;
b = c;
}
num = n/b;
denom = d/b;
}
This is the code that calculates will add numbers from input and calculate the GCD based from those numbers:
Fractions Fractions::operator+(Fractions& fraction2)
{
Fractions totalAddition;
totalAddition.num = (num * fraction2.denom + denom * fraction2.num);
totalAddition.denom = (denom * fraction2.denom);
totalAddition.gcd(num, denom); // i think issue is here
return totalAddition;
}
The only problem here is the name of the function.
A function called gcd should return the Greatest Common Divisor:
int gcd(int n, int d) {
int a, b, c;
a = n;
b = d;
while (a % b != 0) {
c = a % b;
a = b;
b = c;
}
return b;
}
It doesn't need to be a member function of Fraction to do this - it can be a standalone function, which is better, as it makes Fraction more encapsulated. But you can give it an overload which digests Fraction:
int gcd(const Fraction& frac){
return gcd(frac.numerator(), frac.denominator());
}
The name gcd is on the terse side but clear enough in context.
What your function is doing is it's simplifying a fraction, as a member function of a Fraction object, and overwriting that Fraction's member variables. So, it should be called simplify, and it doesn't need to take any input:
void Fractions::simplify() {
int a, b, c;
a = num;
b = denom;
while (a % b != 0) {
c = a % b;
a = b;
b = c;
}
num = n / b;
denom = d / b;
}
You might find you don't need a gcd function in which case simplify will be enough. But if you do need both functions, you can avoid some duplication of code here:
void Fractions::simplify() {
int g = gcd(*this);
num /= g;
denom /= g;
}
//Euclidean algorithm
//if b<a the gcd(a,b)=gcd(a-b,b)
int gcd(int a,int b)
{
while(a!=b)
{
if(a>b)
a=a-b;
else
b=b-a;
}
return a;
}
Output
15 12
3
//Optimal implementation of Euclidean Algorithm
int gcd(int a,int b)
{
if(b==0)
return a;
else
return gcd(b,a%b);
}
Output
15 12
3

How to implement greatest common divisor to simplify fractions

#include <iostream>
using namespace std;
int g_c_d(int n, int d);
class Fraction
{
private:
//variables to store numerator and denominator
int num;
int denom;
public:
Fraction(){}
Fraction(int num): num(num) {}
Fraction(int num, int denom): num(num), denom(denom) {}
void set_num(int n){ num = n;}
void set_denom(int d){ denom = d;}
int get_numerator() const {return num;}
int get_denominator() const {return denom;}
};
int g_c_d(int n, int d){
return d == 0? n : g_c_d(d, n % d);
}
istream &operator>> (istream &input, Fraction &f)
{
int n, d;
char slash;
input >> n;
input >> slash;
input >> d;
if (d == 0) {n = 0;} //if denom is 0; fraction = 0/0
f = Fraction(n, d);
return input;
}
ostream &operator<<(ostream &output, const Fraction &frac)
{
return output << frac.get_numerator() << "/" << frac.get_denominator();
}
int main()
{
int n, d;
Fraction frac;
int gcd;
n = frac.get_numerator();
d = frac.get_denominator();
gcd = g_c_d(frac.get_numerator() , frac.get_denominator());
cout << "Enter a fraction" << endl;
cin >> frac;
frac.set_num(n/gcd);
frac.set_denom(d/gcd);
cout << "your fraction is: ";
cout << frac << endl;
return 0;
}
Hi im trying to simplify fractions entered by a user. However everytime I enter a fraction that is to be simplified the output returned is "1/0".
Can some one please help, it'll be massively appreciated!
The problem is that you do all your computations on frac before asking the user to input a fraction — and then you overwrite whatever the user inputs. You need to move this bit:
cout << "Enter a fraction" << endl;
cin >> frac;
much, much higher up.
When you are setting up the code you have:
Fraction frac;
This calls the default constructor for Fraction. Because you never initialized the members in the constructor you get the default initizliation for the int type which is 0. Then:
n = frac.get_numerator();
d = frac.get_denominator();
This makes n and d 0. From that point onwards you are using those values of n and d. These values however are not the values from the user inputted frac but are just the values you get from the defaults. Change your code to read in the user inputted value for frac before you do any calculations.
The main lesson to learn here is to make sure you don't use uninitialized variables. Generally speaking when you compile with all warnings enabled this is the sort of thing that compilers will warn about.
You may be diving by zero because the default constructor doesn't assign value to the denominator. In the case where the denominator is set to zero, the gcd() function will divide by zero, on the first time in main.

exc_arithmetic error, c++ xcode 4.62

I'm a beginner of c++. I want know why the exception is thrown at this line:
operator double() const
{
return this->denominator/this->numerator;
}
I found numerator == 0,but I have given default values in the ctor. Why? Please help me.
class Rational {
public:
int numerator;
int denominator;
Rational(int numerator = 2, int denominator = 1)
{
numerator = 2;
denominator = 1;
};
operator double() const
{
return this->denominator/this->numerator;
};
};
int main(int argc, const char * argv[])
{
Rational r(1, 2);
cout << r;
// double d = 0.5*r;
return 0;
}
First, this line is very wrong:
Rational(int numerator = 2, int denominator = 1){ numerator = 2; denominator = 1;};
The arguments numerator and denominator are in the stack frame of your ctor thus hiding your class's members Rational::numerator and Rational::denominator and secondly, you are completely ignoring what the caller actually sends as its arguments (not because you specify the default values, but because you explicitly set numerator=2; denominator=1. This line should actually be:
Rational(int numerator = 2, int denominator = 1){ this->numerator = numerator; this->denominator = denominator;};
OR you could use an initializer list (and overloaded constructors):
Rational() : numerator(2), denominator(1) {};
Rational(int numerator, int denominator) : numerator(numerator), denominator(denominator) {};
Now, the second problem is that int/int => int :: dividing an integer by another integer yields integer division, you need to cast one of your int's to double so that both int's are upconverted to double before calculating the division, like so:
operator double() const{ return ((double)this->denominator)/this->numerator;};
Rational(int numerator = 2, int denominator = 1)
{
numerator = 2;
denominator = 1;
};
I would change this to
Rational(int numerator, int denominator)
{
this->numerator = numerator;
this->denominator = denominator;
};
I don't know exactly if this is causing your problem, but I think it's contributing to it. Your call to Rational(int,int) will still work fine and add your specified values into the Object you're creating.
The issue with your code, is scope. I believe you were just re-assigning the arguments/parameters instead of actually re-assigning your instance variables, which I'm assuming was your goal.