Link to home
Start Free TrialLog in
Avatar of Computer Guy
Computer Guy

asked on

Issues with C++ Class

Hello,

I have this application and am wondering in this area
void Fractions::getInput(), why I am not getting a loop when the user enters a 0 in the denominator

also, the gcd is not working.

What am I doing wrong?

# include <iostream>
using namespace std;

class Fractions
{
private:
    int num;
    int denom;

public:
    Fractions(int = 1, int = 1);
    Fractions operator+(Fractions&);
    Fractions operator-(Fractions&);
    Fractions operator*(Fractions&);
    Fractions operator/(Fractions&);

    unsigned int gcd(int num, int denom)
    {
        if(denom == 0) return num;
        return gcd(denom, num % denom);
    }

    void getInput();
    void display();
}; // end of class declaration

// implementation
Fractions::Fractions(int n, int d)
{
    num = n;
    denom = d;
}

// addition
Fractions Fractions::operator+(Fractions& fraction2)
{
    Fractions totalAddition;
    totalAddition.num = num * fraction2.denom + denom * fraction2.num;
    gcd(num,denom);
    totalAddition.denom = denom * fraction2.denom;
    gcd(num,denom);
    return totalAddition;
}

// subtraction
Fractions Fractions::operator-(Fractions& fraction2)
{
    Fractions totalSubtraction;
    totalSubtraction.num = num * fraction2.denom + denom * fraction2.num;
    totalSubtraction.denom = denom * fraction2.denom;
    gcd(num,denom);
    return totalSubtraction;
}

// multiplication
Fractions Fractions::operator*(Fractions& fraction2)
{
    Fractions totalProduct;
    totalProduct.num = num * fraction2.num;
    totalProduct.denom = denom * fraction2.denom;
    gcd(num,denom);
    return totalProduct;
}

// division
Fractions Fractions::operator/(Fractions& fraction2)
{
    Fractions totalDivide;
    totalDivide.num = num * fraction2.denom;
    totalDivide.denom = denom * fraction2.num;
    gcd(num,denom);
    return totalDivide;
}


void Fractions::getInput() {
    cout << "Enter the numerator" << endl;
    cin >> num;

    cout << "Enter the denominator" << endl;
    cin >> denom;

    do
    {
        cin >> denom;
        cout << "Number must be greater than zero";
    } while (denom=0);
}

void Fractions::display()
{
    cout << num << "/" << denom << endl << endl;
}

int main() {

    Fractions fraction1, frection2, result;
    cout << "Enter the first fraction" << endl;
    fraction1.getInput();
    cout << "The first fraction is" << endl;
    fraction1.display();

    cout << "Enter the second fraction" << endl;
    frection2.getInput();
    cout << "The second fraction is" << endl;
    frection2.display();

    result = fraction1 + frection2;
    cout << "Addition" << endl;
    result.display();

    result = fraction1 - frection2;
    cout << "Subtraction" << endl;
    result.display();

    result = fraction1 * frection2;
    cout << "Multiplication" << endl;
    result.display();

    result = fraction1 / frection2;
    cout << "Division" << endl;
    result.display();

    return 0;
}

Open in new window

SOLUTION
Avatar of Zoppo
Zoppo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Computer Guy
Computer Guy

ASKER

Super! Thanks. How about the GCD part?
>> the gcd is not working.
It looks like it is working to me.
I notice in lines 39 and 41 that you are not assigning the gcd return value to a variable.
You are passing in the denom by value, which means that despite it getting modified within the gcd function, the caller does not see the change.
What code do I use to fix that? I'm fried at the moment!
Well, why not save the return gcd return value in a variable?
Did you verify, either with print statements, or preferably by stepping through the code in a debugger that gcd is producing the correct result?
Are you suggestiong something like this?

Fractions Fractions::operator/(Fractions& fraction2)
{
    int test;
    Fractions totalDivide;
    totalDivide.num = num * fraction2.denom;
    totalDivide.denom = denom * fraction2.num;
    test = gcd(num,denom);
    return test;
}

Open in new window

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
When I added this to all for operations, I get the same answer for each one.

Fractions Fractions::operator/(Fractions& fraction2)
{
    int test;
    Fractions totalDivide;
    totalDivide.num = num * fraction2.denom;
    totalDivide.denom = denom * fraction2.num;
    test = gcd(num,denom);
    return test;

Open in new window

Still trying to work this out:

Using test data of 2,4,8,16 (entered separately during each prompt)

It returns:

Addition: 64/64 //(should be 1/1)
Subtraction: 0/32 //(should be 0/1)
Multiplication: 8/32 //(should be 1/4)
Division: 16/16 //(should be 1/1)

# include <iostream>
using namespace std;

class Fractions
{
private:
    int num;
    int denom;

public:
    Fractions(int = 1, int = 1);
    Fractions operator+(Fractions&);
    Fractions operator-(Fractions&);
    Fractions operator*(Fractions&);
    Fractions operator/(Fractions&);
    void gcd(int, int);

    void getInput();
    void display();
}; // end of class declaration

// implementation
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;
}

Fractions::Fractions(int n, int d)
{
    num = n;
    denom = d;

    gcd(num,denom);
}

// addition
Fractions Fractions::operator+(Fractions& fraction2)
{
    Fractions totalAddition;
    totalAddition.num = (num * fraction2.denom + denom * fraction2.num);
    totalAddition.denom = (denom * fraction2.denom);
    gcd(num,denom);
    return totalAddition;
}

// subtraction
Fractions Fractions::operator-(Fractions& fraction2)
{
    Fractions totalSubtraction;
    totalSubtraction.num = num * fraction2.denom - denom * fraction2.num;
    totalSubtraction.denom = denom * fraction2.denom;
    gcd(num,denom);
    return totalSubtraction;
}

// multiplication
Fractions Fractions::operator*(Fractions& fraction2)
{
    Fractions totalProduct;
    totalProduct.num = num * fraction2.num;
    totalProduct.denom = denom * fraction2.denom;
    gcd(num,denom);
    return totalProduct;
}

// division
Fractions Fractions::operator/(Fractions& fraction2)
{
    Fractions totalDivide;
    totalDivide.num = num * fraction2.denom;
    totalDivide.denom = denom * fraction2.num;

    gcd(num,denom);
    return totalDivide;
}


void Fractions::getInput() {
    cout << "Enter the numerator: ";
    cin >> num;

    cout << "Enter the denominator: ";
    cin >> denom;
    while (denom == 0)
    {
        cout << "Number must be not be zero" << endl;
        cin >> denom;
    }
}

void Fractions::display()
{
    cout << num << "/" << denom << endl;
}

int main() {

    Fractions fraction1, fraction2, result;
    cout << "First Fraction" << endl;
    fraction1.getInput();

    cout << "Second Fraction" << endl;
    fraction2.getInput();

    result = fraction1 + fraction2;
    cout << "Addition: ";
    result.display();

    result = fraction1 - fraction2;
    cout << "Subtraction: ";
    result.display();

    result = fraction1 * fraction2;
    cout << "Multiplication: ";
    result.display();

    result = fraction1 / fraction2;
    cout << "Division: ";
    result.display();

    return 0;
}

Open in new window

you have divide both the num and denom of the return object by the value returned from gcd.

// addition
Fractions Fractions::operator+(Fractions& fraction2)
{
    Fractions totalAddition;
    totalAddition.num = (num * fraction2.denom + denom * fraction2.num);
    totalAddition.denom = (denom * fraction2.denom);
    int igcd = gcd(num,denom);
    if (igdc > 0)
    {
         totalAddition.num /= igdc;
         totalAddition.denom /= igdc;
    }
    return totalAddition;
}

Open in new window


you should make a member function from the gcd call and the if block and then use that function before return.

Sara
I receive a Types int and void are not compatible message.
check the prototype of your gcd function. should be like

int gcd ( int a, int b );

Open in new window


what means it would return the greatest common divisor between a and b.

if your gcd function returns void post it or replace it by

/* Standard C Function: Greatest Common Divisor */
int mygcd ( int a, int b )
{
  int c;
  while ( a != 0 ) {
     c = a; a = b%a;  b = c;
  }
  return b;
}

Open in new window


Sara
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I'm still not grasping. I have tried a few combinations, none have worked.
if you don't post errors and error lines we hardly can help.

note, the gcd function in your original post looks fine. you also could replace it by the function i posted.

Sara
What do you mean by:

"your second implementation has type void what is wrong. gcd must return the divisor as int or unsigned "
I mean the following in #a41919010

// implementation
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;
}

Open in new window


where you have a member function which doesn't return the divisor but made the cancel operation onto the members.

it is a valid function as well but i wouldn't name it gcd but cancel and you would use it like

void Fractions::cancel(int n, int d)
{
    // calculate gcd
    ...
   // divide num and denom by gcd 
   ...
}
....
// addition
Fractions Fractions::operator+(Fractions& fraction2)
{
    Fractions totalAddition;
    totalAddition.num = (num * fraction2.denom + denom * fraction2.num);
    totalAddition.denom = (denom * fraction2.denom);
    // get the gcd of totalAddition and divide the members 
    totalAddition.cancel();  // important: the operator+ returns totalAddition and not the *this
    return totalAddition;
}

Open in new window


Sara
So that changes gcd to cancel:

void Fractions::cancel(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;
}

Open in new window


And the operations to this:

// addition
Fractions Fractions::operator+(Fractions& fraction2)
{

    Fractions totalAddition;
    totalAddition.num = (num * fraction2.denom + denom * fraction2.num);
    totalAddition.denom = (denom * fraction2.denom);
    totalAddition.cancel(num, denom);
    return totalAddition;
}

Open in new window


Which give 1/2, not 1/1

What am I missing?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial