Unexpected addition operator with my class - c++

I apologize if the question is Naive.
I am trying to overload the addition operator for fractions. My intent was to add fractions but for some reason it is adding the integers. Can some one explain why is it performing the integer addition. Code is below.
#include <iostream>
#include <string>
using namespace std;
class Fraction{
long numerator;
long denominator;
long gcd(long num1, long num2);
long lcm(long num1, long num2);
public:
void convert_int_to_fraction(int num);
void reduce();
Fraction(int num);
Fraction(){
numerator = 0;
denominator = 0;
}
Fraction(long num, long den);
Fraction operator+(Fraction fraction);
friend ostream& operator<<(ostream& os, const Fraction& fracNumber);
};
void Fraction::convert_int_to_fraction(int num){
denominator = 1;
numerator = long(num);
reduce();
}
Fraction::Fraction(int num){
convert_int_to_fraction(num);
}
long Fraction::gcd(long num1, long num2){
if(num1 == 0)
return num2;
else
return (gcd(num2 % num1, num1));
}
//Math function to calculate LCM
long Fraction::lcm(long num1, long num2){
long great_Divisor = gcd(num1, num2);
return ((num1/great_Divisor) * num2);
}
//Reduce fraction to its minimal
void Fraction::reduce(){
if(denominator!=0){
long great_Divisor = gcd(numerator, denominator);
numerator /= great_Divisor;
denominator /= great_Divisor;
if(denominator < 0 && numerator > 0){
denominator = -denominator;
numerator = -numerator;
}
}
}
Fraction::Fraction(long num, long den):numerator(num), denominator(den){
reduce();
}
ostream& operator<<(ostream& os, const Fraction& fracNumber){
os << fracNumber.numerator << "/" << fracNumber.denominator ;
return os;
}
Fraction Fraction::operator+(Fraction fraction){
Fraction result;
long least_Multiple = lcm(denominator, fraction.denominator);
result.denominator = (least_Multiple);
long result_Numerator = ((numerator * (least_Multiple/denominator)) +
(fraction.numerator * (least_Multiple/fraction.denominator)));
result.numerator = (result_Numerator);
result.reduce();
return result;
}
int main(){
Fraction frac1(2,4);
cout << frac1 + 2 << endl;
return 0;
}
The output is 5/2 So I tried to do it the other way round
cout << 2 + frac1 << endl;
This is giving me error. So now I tried to fix this by implementing these two functions.
Fraction::operator int(){
return convert_fraction_to_int();
}
int Fraction::convert_fraction_to_int(){
return ((int)(numerator/denominator));
}
Now even the first operation cout doesnt work. But the best thing is everything works fine when I typecast the variables. Can anyone explain why it is working in the first case, why not in the second case and why broken in the third case.

.My intent was to add fractions but for some reason it is adding the integers. Can some one explain why is it performing the integer addition.
There is a converting constructor from int to Fraction.
frac1 + 2 is being converted to frac1 + Fraction(2) by the compiler.
Update
If you want the compiler to be able support both frac1 + 2 and 2 + frac1, you can make the operator+ function a non-member function.
friend Fraction operator+(Fraction const& lhs, Fraction const& rhs);
and implement it as:
Fraction operator+(Fraction const& lhs, Fraction const& rhs)
{
Fraction result;
// Needed to make lcm and gcd static member functions since
// they work independent of the member variables.
long least_Multiple = Fraction::lcm(lhs.denominator, rhs.denominator);
result.denominator = (least_Multiple);
long result_Numerator = ((lhs.numerator * (least_Multiple/lhs.denominator)) +
(rhs.numerator * (least_Multiple/rhs.denominator)));
result.numerator = (result_Numerator);
result.reduce();
return result;
}
Now, you can use
Fraction frac1(2,4);
Fraction frac2(3,7);
cout << frac1 + 2 << endl;
cout << 3 + frac1 << endl;
cout << frac1 + frac2 << endl;

Related

Don't know what Im doing wrong-adding,subtracting,dividing,multiplying rationals in c++

This is the code that I wrote so far. Not sure what I am doing wrong. Every time I try to run it it displays "Invalid operands to binary expression" next to the "cin >> rational_2;" in the main file. If there is any that could help me I could deeply appreciate it. Also, provided the description what I need to do at the bottom.
Rational Arithmetic I
A rational number is a quotient of two integers. For example, 12/5, 12/–4, –3/4, and 4/6 are all rational numbers. A rational number is said to be in reduced form if its denominator is positive and its numerator and denominator have no common divisor other than 1. For example, the reduced forms of the rational numbers given above are 12/5, –3/1, –3/4, and 2/3.
Write a class called Rational with a constructor Rational(int, int) that takes two integers, a numerator and a denominator, and stores those two values in reduced form in corresponding private members. Ensure that the denominator is not 0. The class should have a private member function void reduce() that is used to accomplish the transformation to reduced form. The class should have an overloaded insertion operator << that will be used for output of objects of the class.
Rational Arithmetic II
Modify the class Rational of Programming Challenge 8 to add overloaded operators +, −, *, and / to be used for addition, subtraction, multiplication, and division.
#include <iostream>
using namespace std;
class Rational
{
private:
int denom;
int numer;
void reduce();
public:
Rational();
Rational(int num, int den);
//********** overloading mathematical operators ************
Rational operator-(const Rational& rightFr);
Rational operator*(const Rational& rightFr);
Rational operator/(const Rational& rightFr);
Rational operator+(const Rational& rightFr);
//********** overloading relational operators ************
bool operator == (const Rational& rightFr);
// F R I E N D F U N C T I I O N S
friend ostream& operator<<(ostream& the_output, Rational&);
};
//Rational.cpp file
#include "Rational.h"
Rational::Rational()
{
}
Rational::Rational(int num, int den)
{
numer = num;
denom = den;
reduce();
}
// reduce method
void Rational::reduce()
{
int topnum;
if (numer > denom )
{
topnum = numer;
}
else
{
topnum = denom;
}
int divisor = 2;
while (divisor <= topnum)
{
if (numer%divisor == 0 && denom%divisor == 0)
{
numer /= divisor;
denom /= divisor;
divisor =2;
}
else
{
divisor++;
}
}
if(denom < 0 )
{
denom *= -1;
numer *= -1;
}
}
// Operator Overload for Adding
Rational Rational:: operator+(const Rational &rightFr){
Rational ret_val( 1, 1);
ret_val.numer = this ->numer * rightFr.denom + this->denom * rightFr.numer;
ret_val.denom = this-> denom + rightFr.denom;
return ret_val;
}
// Operator Overload for Sub
Rational Rational:: operator-(const Rational &rightFr){
Rational ret_val( 1, 1);
ret_val.numer = this ->numer * rightFr.denom - this->denom * rightFr.numer;
ret_val.denom = this-> denom - rightFr.denom;
return ret_val;
}
// Operator Overload for Mult.
Rational Rational::operator * (const Rational &rightFr){
Rational ret_val(1,1);
ret_val.numer = this ->numer * rightFr.numer;
ret_val.denom = this ->numer * rightFr.numer;
reduce();
return ret_val;
}
Rational Rational::operator / (const Rational &rightFr){
Rational ret_val(1,1);
ret_val.numer = this ->numer * rightFr.numer;
ret_val.denom = this ->denom * rightFr.denom;
reduce();
return ret_val;
}
bool Rational::operator==(const Rational &rightFr)
{
bool answer = false;
if( numer == rightFr.numer && this-> denom == rightFr.denom)
{
answer = true;
}
return answer;
}
// friend functions
ostream& operator<<(ostream& the_output, Rational& obj ){
the_output << obj.numer <<"/"<< obj.denom << endl;
return the_output;
}
//main file
#include <iostream>
#include <iomanip>
#include "Rational.h"
using namespace std;
int main()
{
Rational rational_1(5, 6);
Rational rational_2;
Rational rational_Add, rational_Sub, rational_Mult, rational_Divide;
cout << "Enter numerator and denominator separated by a space :";
cin >> rational_2; // this is were I get the error
rational_Add = rational_1 + rational_2;
rational_Sub = rational_1 - rational_2;
rational_Mult = rational_1 * rational_2;
rational_Divide = rational_1 / rational_2;
cout << "rational_1 : " << rational_1 << endl
<< "rational_2 : " << rational_2 << endl
<< "rational_Add : " << rational_Add << endl
<< "rational_Sub : " << rational_Sub << endl
<< "rational_Mult : " << rational_Mult << endl
<< "rational_Divide : " << rational_Divide << endl;
return 0;
}
cin >> rational_2; // this is were I get the error
Please implement istream operator overloading operator>>. For example,
friend istream& operator>>(istream& is, Rational& obj) {
is >> obj.numer >> obj.denom;
return is;
}

Fraction class for finding square root 2 convegerence

I made a class that can add, multiply and divide fractions which is presented below
class fraction
{
unsigned long long num, denom;
public:
fraction(int n, int d): num{n}, denom{d} {};
fraction& operator+=(fraction frac);
fraction& operator*=(fraction frac);
fraction& operator/=(fraction frac);
friend ostream& operator<<(ostream& os, const fraction& frac);
};
fraction& fraction::operator+=(fraction frac)
{
unsigned long long least_mult = lcm(denom, frac.denom); // Least-Common Multiple
num *= least_mult/denom;
num += frac.num*least_mult/frac.denom,
denom = least_mult;
return *this;
}
fraction& fraction::operator*=(fraction frac)
{
num *= frac.num;
denom *= frac.denom;
return *this;
}
fraction& fraction::operator/=(fraction frac)
{
num *= frac.denom;
denom *= frac.num;
return *this;
}
ostream& operator<<(ostream& os, const fraction& frac)
{
os << frac.num << '/' << frac.denom;
return os;
}
fraction operator+(fraction a, fraction b) {return a+=b;}
fraction operator*(fraction a, fraction b) {return a*=b;}
fraction operator/(fraction a, fraction b) {return a/=b;
}
When I try to compute square root two convergence using sqrt_two = 1 + 1/(1+sqrt_two) recursive relation when I get up to 4478554083/3166815962, the next value is 8399386631/7645270045 which is totally off as it is about 1.098, and therefore all the subsequent values are wrong too.
int main()
{
fraction one(1, 1), sqrt_two(3,2);
for(int i = 1; i < 50; ++i)
{
sqrt_two = one + one/(one+sqrt_two);
cout << sqrt_two << endl;
}
return 0;
}
I have tried 1+1/(1+8399386631/7645270045)) manually on a calculator and the result is still a square root convergent.
Looking at your code, there are lines that are susceptible to overflow. Perhaps one has happened in this case. For example,
num += frac.num*least_mult/frac.denom,
(which looks like it contains a typo, incidentally).
So, I'd suggest you see how to check for overflow, and then somehow incorporate it into your class. I'm not sure what you should do in such a case, though.
To compute the step that gives bad results you multiply two numbers of about 32 bits. The result exceeds the long long size (64 bit if unsigned) and you end up having wrong result because of overflow. A calculator (using more bits or silently converting to floating point) overcomes this problem.

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.

Overloading operator + for fractions (using lcm)

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).

What of lack this program? (sorting with qsort, struct array)

I'm create Fraction Struct Array Sorting program.
a little number (slightly under 1000) my program have good answer
but big number (slightly over 100000) my program have wrong answer
what's the problem?
this is my source and input data
#include <cstdlib>
#include <iostream>
using namespace std;
struct Fraction {
long long denominator;
long long numerator;
};
int compare(const void *a, const void *b) {
const struct Fraction *x = (Fraction *)a;
const struct Fraction *y = (Fraction *)b;
long long val = x->numerator * y->denominator - x->denominator * y->numerator;
if (val == 0) {
return x->numerator - y->numerator > 0 ? 1 : -1;
} else {
return val;
}
}
Fraction setOfData[100000];
int numOfData, numOfK;
int main() {
cin >> numOfData >> numOfK;
for (int i = 0; i < numOfData; ++i) {
long long denominator;
long long numerator;
cin >> numerator >> denominator;
setOfData[i].numerator = numerator;
setOfData[i].denominator = denominator;
}
qsort(setOfData, numOfData, sizeof(Fraction), compare);
cout<< setOfData[numOfK - 1].numerator << ' ' << setOfData[numOfK - 1].denominator;
return 0;
}
and this is my input data
input data
7 4
56783 9765493
56786 9765492
56788 9765491
8888888 9765464
56687 9765395
56789 9765497
56785 9765496
sorting standard is non-decreasing
over input data my program print
8888888 9765464
56687 9765395
56783 9765493
56785 9765496
56786 9765492
56788 9765491
56789 9765497
what's the lack of this program? is it long long? or int?
help me plz...
Try this in compare
return val > 0 ? +1 : -1;
I expect that you are losing precision when the long long int is converted to an int when you return from compare.