0

So I'm writing a mixed numerals class for my OO class. We need to overload every comparison and boolean operand (among other things) but I'm having trouble with how to think about the '<' and '>' operands. Here are my '==' and '!=' operand functions for some context.

Edit: Also If anyone has any tips for to addition/subtraction methods I would be grateful.

bool operator ==(Mixed& mn1, Mixed& mn2){

mn1.ToFraction();
mn2.ToFraction();

mn1.Simplify();
mn2.Simplify();

if(mn1.numerator == mn2.numerator && mn1.denominator == mn2.denominator)
    return true;
else
    return false;
}

and

bool operator !=( Mixed& mn1,  Mixed& mn2){
mn1.ToFraction();
mn2.ToFraction();

mn1.Simplify();
mn2.Simplify();

if(mn1.numerator == mn2.numerator && mn1.denominator == mn2.denominator)
    return false;
else
    return true;
}

If anyone could offer some guidance I'd be appreciative. Oh and we can't convert them to decimals for the comparisons.

Edit: Here's my header.

#include <iostream>

using namespace std;

class Mixed
{
public:
Mixed(int integer, int numerator = 0, int denominator = 1);
Mixed(int integer = 0);
double Evaluate();
void ToFraction();
void Simplify();

friend istream& operator >>(istream& in, Mixed& mn);
friend ostream& operator <<(ostream& out, Mixed& mn);

friend bool operator ==( Mixed& mn1,  Mixed& mn2);
friend bool operator !=( Mixed& mn1,  Mixed& mn2);
friend bool operator >( Mixed& mn1,  Mixed& mn2);
friend bool operator <( Mixed& mn1,  Mixed& mn2);
friend bool operator <=( Mixed& mn1,  Mixed& mn2);
friend bool operator >=( Mixed& mn1,  Mixed& mn2);

friend const Mixed operator +( Mixed& mn1,  Mixed& mn2);
friend const Mixed operator -( Mixed& mn1,  Mixed& mn2);
friend const Mixed operator *( Mixed& mn1,  Mixed& mn2);
friend const Mixed operator /( Mixed& mn1,  Mixed& mn2);

private:
int GCD(int a, int b);
int integer, numerator, denominator;
};
Woot4Moo
  • 23,987
  • 16
  • 94
  • 151
Connor Black
  • 6,921
  • 12
  • 39
  • 70
  • 1
    Do change your arguments to `Mixed const&` – K-ballo Jun 08 '12 at 23:27
  • If I do that I lose the ability to call my ToFraction() and Simplify() functions. – Connor Black Jun 08 '12 at 23:28
  • Does "mixed numeral" mean "rational number"? – Kerrek SB Jun 08 '12 at 23:28
  • 1
    @Connor Black: If you don't you loose the ability to compare _rvalues_. `ToFraction` should probably be `const` already. Plus a logical operator that changes its arguments is a dangerous beast at least... – K-ballo Jun 08 '12 at 23:30
  • http://en.wikipedia.org/wiki/Fraction_(mathematics)#Mixed_numbers – Connor Black Jun 08 '12 at 23:30
  • @ConnorBlack, But calling those functions will change the objects themselves. If you do want the objects simplified and fractions, do it when they're modified, not compared. Also, it's better to implement `operator!=` like `return !(*this == other);`. Less code to write, less to maintain, and less chance of random errors. – chris Jun 08 '12 at 23:30
  • @Chris, I don't have control over the driver program – Connor Black Jun 08 '12 at 23:33
  • 1
    @K-ballo: `ToFraction` can't be const, as it modifies the object. He'll have to use copies of the objects to do the comparisons. He should probably have them receive their arguments by value. – Mooing Duck Jun 09 '12 at 00:05
  • @Mooing Duck: I assumed `ToFraction` would return a _fraction_ instead, as its usually the case with `ToXXX` functions. – K-ballo Jun 09 '12 at 00:06

2 Answers2

2

Rational numbers are really quite straight forward: A rational number is a pair (a, b) of integers, usually written as a / b, up to the equivalence that (a, b) ≡ (a', b') if and only if ab' = a'b.

So if your class contains two representative integers p and q, you can implement the equality operator as:

struct Rational
{
    int p;            // numerator
    unsigned int q;   // denominator

    bool operator==(Rational const & rhs) const
    {
        return p * rhs.q == rhs.p * q;
    }

    // ...
};

For two positive rationals, you have inequality via p * rhs.q < rhs.p * q. All the other relations can be implemented in terms of those two, e.g. x <= y is the same as !(y < x) etc.

Cancellation of rationals to lowest terms can be done by dividing both numerator and denominator by their GCD, as you already appear to have implemented.

"Mixed" numbers, i.e. integer plus rational-smaller-than-one, are trivially converted into the usual numerator-denominator rational representation for manipulation, and back to mixed form by integral division and remainder.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 1
    Just so I'm following you correctly, p and q in your example are representing the numerator and denominator, respectively? – Connor Black Jun 08 '12 at 23:38
  • Any tips for getting the denominators to be equal for the addition and subtraction overloading methods? – Connor Black Jun 08 '12 at 23:51
  • 1
    One possibility is to multiply each by one in the form of `other.denom/other.denom`. Add, then reduce to lowest terms. – Jerry Coffin Jun 08 '12 at 23:57
  • I'm a little confused. Are you saying to add 1/2 and 3/4 you would do (1/2 * 2/4) + (3/4 *2/4)? – Connor Black Jun 09 '12 at 00:13
  • 1
    No, he's saying to add 1/2 and 3/4 you could do (1/2 * 4/4) + (3/4 * 2/2) = 4/8 + 6/8 = 10/8 = 5/4 = 1 1/4 – Bill Jun 09 '12 at 00:54
  • Just beware of integer promotion rules & overflow in this example (at least an overflow would be well-defined since both terms will be unsigned int). I just finished debugging and correcting a slew of company code with problems due to integer promotion and due to undefined behavior (overflow of signed values, not an issue here). I'm 100% sure that @Kerrek SB is aware of all this, but I'm not sure if the OP (or others reading) will realize this. – Dan Jun 09 '12 at 18:41
1

To compare rationals, you normally want to find a common denominator, then compare the numerators. For such a comparison, you don't really need to reduce to lowest terms either (though it's quick/easy enough that doing so is generally fairly harmless).

If you decide to keep your equality comparisons as they are, you can simplify them a bit to something like:

bool operator ==(Mixed mn1, Mixed mn2){    
    mn1.ToFraction();
    mn2.ToFraction();

    mn1.Simplify();
    mn2.Simplify();

    return mn1.numerator == mn2.numerator && mn1.denominator == mn2.denominator;
}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111