Negating a fraction but not modifying the original - c++

I have written the following class for modifying a Fraction object.
#include "Fraction.h"
#include "GCD.h"
#include <iostream>
using std::cout;
//Implementation of the timesEq() member function
//Performs similar operation as the *= operator on the built-in types
const Fraction & Fraction::timesEq(const Fraction & op )
{
numerator *= op.numerator;
denominator *= op.denominator;
simplify(); // will make sure that denominator is positive and
// will invoke gcd() function to reduce fraction
// as much as possible
return (*this); // returns the object which invoked the method
}
const Fraction & Fraction::plusEq (const Fraction & op )
{
numerator *= op.denominator;
numerator += op.numerator * denominator;
denominator *= op.denominator;
simplify(); // will make sure that denominator is positive and
// will invoke gcd() function to reduce fraction
// as much as possible
return (*this); // returns the object which invoked the method
}
const Fraction & Fraction::minusEq (const Fraction & op )
{
numerator *= op.denominator;
denominator = denominator * op.denominator;
numerator -= op.numerator;
simplify(); // will make sure that denominator is positive and
// will invoke gcd() function to reduce fraction
// as much as possible
return (*this); // returns the object which invoked the method
}
const Fraction & Fraction::divideEq (const Fraction & op )
{
numerator *= op.denominator;
denominator *= op.numerator;
simplify(); // will make sure that denominator is positive and
// will invoke gcd() function to reduce fraction
// as much as possible
return (*this); // returns the object which invoked the method
}
Fraction Fraction::negate(void) const
{
return (*this * -1);
}
void Fraction::display(void)const {
cout << numerator << "/" << denominator;
}
void Fraction::simplify(void)
{
gcd = gcd(numerator, denominator);
numerator /= gcd;
denominator /= gcd;
}
But am having trouble with the negate function.
I am using the function like so: B = A.negate(), and as such, I cannot modify the original A object, but need to assign the negated object to B.
Right now the implementation I have is giving an error:
Error: no operator "*" matches these operands
operand types are: const Fraction * int
I'm not sure what I am doing wrong. What needs to be changed?

Assuming you have a constructor that takes two ints as arguments (if you don't, you should, and not just for the sake of my answer), do this:
return Fraction(-numerator, denominator);

Related

How to fix "*private variable* is a private member of '*class name*' error

I'm writing code that uses friend functions but I am not sure why I get the error "is a private member of" in the function "sum" since I declared the function as a friend in the header file.
Header File:
#include <iostream>
class rational
{
public:
// ToDo: Constructor that takes int numerator and int denominator
rational (int numerator = 0, int denominator = 1);
// ToDo: Member function to write a rational as n/d
void set (int set_numerator, int set_denominator);
// ToDo: declare an accessor function to get the numerator
int getNumerator () const;
// ToDo: declare an accessor function to get the denominator
int getDenominator () const;
// ToDo: declare a function called Sum that takes two rational objects
// sets the current object to the sum of the given objects using the
// formula: a/b + c/d = ( a*d + b*c)/(b*d)
friend rational sum (const rational& r1, const rational& r2);
void output (std::ostream& out);
// member function to display the object
void input (std::istream& in);
private:
int numerator;
int denominator;
};
Source File:
#include <iostream>
using namespace std;
// takes two rational objects and uses the formula a/b + c/d = ( a*d + b*c)/(b*d) to change the numerator and denominator
rational sum (rational r1, rational r2)
{
// formula: a/b + c/d = ( a*d + b*c)/(b*d)
cout << endl;
numerator = ((r2.denominator * r1.numerator) + (r1.denominator * r2.numerator));
denominator = (r1.denominator * r2.denominator);
}
rational sum (rational r1, rational r2) is a totally new function (no way to relate to the class rational) that accepts two rationals and returns a rational.
The correct way to implement the needed class method would be rational rational::sum (const rational& r1, const rational& r2)
Overall comment: Use capitalized first letter for classes (Rational)
You want something like this:
rational sum (const rational& r1, const rational& r2)
{
// formula: a/b + c/d = ( a*d + b*c)/(b*d)
int numerator = ((r2.denominator * r1.numerator) + (r1.denominator * r2.numerator));
int denominator = (r1.denominator * r2.denominator);
return rational(numerator, denominator);
}

Unexpected addition operator with my class

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;

multiplicative inverse of rational numbers c++

My program works fine except when a fraction has a numerator of 0 in the numerator when it does the inverse I get an arithmetic error and it crashes.
I've tried to check for zero int he numerator several different ways but I can't get the program to compile. Can someone give me some pointers.
Here's my code so far:
#include <lab58.h>
using namespace std;
int lcm(int u, int v)
{
if(u == 0 || v == 0)
return 0;
else
return (u * v) / gcd(u, v);
}
Rational rationalAdd(const Rational& augend, const Rational& addend)
{
Rational sum;
int lcm = ::lcm(augend.denominator, addend.denominator);
sum.numerator = lcm * augend.denominator / augend.numerator +
lcm * addend.denominator / addend.numerator;
sum.denominator = lcm;
rationalNormalize(sum);
return sum;
}
Rational rationalAdditiveInverse(const Rational *rational)
{
Rational additiveInverse;
additiveInverse.numerator = rational->numerator * -1;
additiveInverse.denominator = rational->denominator;
return additiveInverse;
}
Rational rationalSubtract(const Rational& minuend, const Rational& subtrahend)
{
return rationalAdd(minuend, rationalAdditiveInverse(&subtrahend));
}
// Function rationalMultiply returns multiplier x multiplicand. The
// result is returned in reduced form.
Rational rationalMultiply(const Rational& multiplier, const Rational& multiplicand)
{
Rational product;
product.numerator = multiplier.numerator * multiplicand.numerator;
product.denominator = multiplier.denominator * multiplicand.denominator;
rationalNormalize(product);
return product;
}
// Function rationalMultiplicativeInverse returns the multiplicative inverse.
// The multiplicative inverse, or reciprocal, of a number a is the
// number that, when multiplied by a, yields the multiplicative
// identity, 1. The multiplicative inverse of the fraction a/b is b/a.
Rational rationalMultiplicativeInverse(const Rational *rational)
{
Rational multiplicativeInverse;
multiplicativeInverse.numerator = rational->denominator;
multiplicativeInverse.denominator = rational->numerator;
return multiplicativeInverse;
}
// Function rationalDivide returns dividend / divisor. The result is
// returned in reduced form.
Rational rationalDivide(const Rational& dividend, const Rational& divisor)
{
return rationalMultiply(dividend, rationalMultiplicativeInverse(&divisor));
}
Here's the lab58.h file:
#ifndef LAB58_H
#define LAB58_H
#include <lab57.h>
using namespace std;
// Function lcm returns the least common multiple of u & v
int lcm(int u, int v);
// Function rationalAdd returns augend + addend. The result is
// returned in reduced form.
Rational rationalAdd(const Rational& augend, const Rational& addend);
// Function rationalAdditiveInverse returns the additive inverse.
// The additive inverse, or opposite, of a number a is the number
// that, when added to a, yields zero. Thus, the fraction a/b is
// returned as -a/b.
Rational rationalAdditiveInverse(const Rational *rational);
// Function rationalSubtract returns minuend - subtrahend. The result
// is returned in reduced form.
Rational rationalSubtract(const Rational& minuend, const Rational& subtrahend);
// Function rationalMultiply returns multiplier x multiplicand. The
// result is returned in reduced form.
Rational rationalMultiply(const Rational& multiplier, const Rational& multiplicand);
// Function rationalMultiplicativeInverse returns the multiplicative inverse.
// The multiplicative inverse, or reciprocal, of a number a is the
// number that, when multiplied by a, yields the multiplicative
// identity, 1. The multiplicative inverse of the fraction a/b is b/a.
Rational rationalMultiplicativeInverse(const Rational *rational);
// Function rationalDivide returns dividend / divisor. The result is
// returned in reduced form.
Rational rationalDivide(const Rational& dividend, const Rational& divisor);
#endif
Lab57.h:
/*
* Prototypes for operations on rational numbers.
*/
#ifndef LAB57_H
#define LAB57_H
#include <iostream>
using namespace std;
typedef struct
{
int numerator;
int denominator;
} Rational;
// Function rationalValid returns true if rational represents a valid
// rational number and false otherwise.
bool rationalValid(const Rational& rational);
// Function rationalNormalize reduces rational to lowest
// terms. Negative rationals should be manipulated so that the
// minus sign goes with the numerator. Zero is represented by zero
// (0) as the numerator and one (1) as the denominator.
void rationalNormalize(Rational& rational);
// Function rationalInput initializes rational from input stream in
istream& rationalInput(istream& in, Rational& rational);
// Function rationalOutput writes rational to output stream out in the
// format rational.numerator/rational.denominator
ostream& rationalOutput(ostream& out, const Rational& rational);
// Function gcd returns the greatest common divisor of u & v
int gcd(int u, int v);
#endif
Lab57main.C:
#include <iostream>
#include <lab57.h>
using namespace std;
int main()
{
Rational rational;
while (rationalInput(cin, rational))
{
if (rationalValid(rational))
{
rationalOutput(cout, rational);
cout << " = ";
rationalNormalize(rational);
rationalOutput(cout, rational);
cout << endl;
}
else
{
rationalOutput(cout, rational);
cout << " is invalid " << endl;
}
}
return EXIT_SUCCESS;
}

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.

+= Overloading in C++ problem

I am trying to overload the += operator for my rational number class, but I don't believe that it's working because I always end up with the same result:
RationalNumber RationalNumber::operator+=(const RationalNumber &rhs){
int den = denominator * rhs.denominator;
int a = numerator * rhs.denominator;
int b = rhs.numerator * denominator;
int num = a+b;
RationalNumber ratNum(num, den);
return ratNum;
}
Inside main
//create two rational numbers
RationalNumber a(1, 3);
a.print();
RationalNumber b(6, 7);
b.print();
//test += operator
a+=(b);
a.print();
After calling a+=(b), a is still 1/3, it should be 25/21. Any ideas what I am doing wrong?
operator+= is supposed to modify the object itself and return a reference. You are instead creating a new object and returning that. Something like this might work (untested code):
RationalNumber &RationalNumber::operator+=(const RationalNumber &rhs){
int den = denominator * rhs.denominator;
int a = numerator * rhs.denominator;
int b = rhs.numerator * denominator;
int num = a+b;
numerator = num;
denominator = den;
return *this;
}
Likewise operator+ should return a new object and can almost always be implemented in terms of operator+=:
RationalNumber RationalNumber::operator+(const RationalNumber &rhs){
RationalNumber tmp(*this);
tmp += rhs;
return tmp;
}
Finally, (now i'm getting off topic) it is usually considered best practice to use free functions instead of members where you can for things like binary operators.
You are not changing the object the operator is applied to.
x += 3;
should change x.