First of all, disclaimer; this is for a school assignment. I hope I'm not doing anything inappropriate by asking for input on it, but if it makes a difference, the assignment has already been submitted and graded.
I've been having some problems with the professor that submitted the assignment, but I value my education and want to understand this as much as possible. He just announced in class that he will no longer be answering questions via email, and that we'll have to attend his office hours if we have any. This is a bit of a problem for me as I'm working full time while in school.
The assignment was to implement a Rational number class from a header that he provided. We aren't allowed to modify the contents of the header and are required to implement the class exactly as it's found there.
To make a long story short, there's a section on the submission website where he posts feedback for us on our assignments. My feedback was "Too many errors to list" and nothing else. I'm at a loss, I'm sure my code isn't perfect but I felt like I tested it pretty thoroughly at it always produced the expected output.
If anyone more experienced/knowledgeable than me would be kind enough to review my code and help me understand some of the errors he may be referring to, I'd really appreciate it. I plan on finding a chance to go into his office hours, but he's got a very eclectic way of explaining things and seems to view explaining concepts to students as an inconvenience, so I don't want to put all my eggs in that basket. Its frustrating because I do a ton of outside reading, I'm really motivated to learn and spend a ton of time helping other students in that class understand the concepts that he doesn't lecture on. I'm just at a loss for what I'm missing here.
Here's the code: As I mentioned, Rational.h is provided by him and we can't change it. I don't like some things about it (like the using namespace std in the header), but I can't do anything about it unfortunately.
Rational.h
#ifndef _RATIONAL_H_ #define _RATIONAL_H_ #include<iostream> using namespace std; class Rational { long long _p; long long _q; void simplify(); public: Rational(); Rational (long long p, long long Q = 1); Rational (const Rational&); Rational& operator= (const Rational&); Rational& operator+= (const Rational&); Rational& operator-= (const Rational&); Rational& operator*= (const Rational&); Rational& operator/= (const Rational&); friend ostream& operator<< (ostream&, const Rational&); friend istream& operator>> (istream&, Rational&); Rational operator+ (const Rational&); Rational operator+ (long long) const; friend Rational operator+ (long long, const Rational&); Rational operator- (const Rational&); Rational operator- (long long) const; friend Rational operator- (long long, const Rational&); Rational operator* (const Rational&); Rational operator* (long long) const; friend Rational operator* (long long, const Rational&); Rational operator/ (const Rational&); Rational operator/ (long long) const; friend Rational operator/ (long long, const Rational&); bool operator== (const Rational&) const; bool operator== (long long) const; friend bool operator== (long long, const Rational&); bool operator!= (const Rational&) const; bool operator!= (long long) const; friend bool operator!= (long long, const Rational&); bool operator> (const Rational&) const; bool operator> (long long) const; friend bool operator> (long long, const Rational&); bool operator< (const Rational&) const; bool operator< (long long) const; friend bool operator< (long long, const Rational&); bool operator>= (const Rational&) const; bool operator>= (long long) const; friend bool operator>= (long long, const Rational&); bool operator<= (const Rational&) const; bool operator<= (long long) const; friend bool operator<= (long long, const Rational&); Rational operator++ (int); Rational operator-- (int); Rational& operator++ (); Rational& operator-- (); Rational operator- () const; Rational operator+ () const; Rational pow (unsigned exp) const; Rational inverse() const; }; #endif
Rational.cpp
#include "Rational.h"
#include <iostream>
void validate (long long, long long);
int gcd (long long, long long);
Rational::Rational()
{
_p = 0;
_q = 1;
}
Rational::Rational (long long p, long long Q)
{
validate (p, Q);
_p = p;
_q = Q;
}
Rational::Rational (const Rational& rat)
{
this->_p = rat._p;
this->_q = rat._q;
}
void Rational::simplify()
{
// Fixes negative denominators.
if (_q < 0)
{
_p *= -1;
_q *= -1;
}
// Simplifies Rational Numbers.
int denom = gcd(_p, _q);
_p /= denom;
_q /= denom;
}
Rational& Rational::operator= (const Rational& rat)
{
_p = rat._p;
_q = rat._q;
return *this;
}
Rational& Rational::operator+= (const Rational& rat)
{
_p = ((_p * rat._q) + (_q * rat._p));
_q *= rat._q;
this->simplify();
return *this;
}
Rational& Rational::operator-= (const Rational& rat)
{
_p = ((_p * rat._q) - (_q * rat._p));
_q *= rat._q;
this->simplify();
return *this;
}
Rational& Rational::operator*= (const Rational& rat)
{
_p *= rat._p;
_q *= rat._q;
this->simplify();
return *this;
}
Rational& Rational::operator/= (const Rational& rat)
{
if (rat._p == 0)
{
throw "Division by zero not allowed";
}
_p *= rat._q;
_q *= rat._p;
this->simplify();
return *this;
}
ostream& operator<< (ostream& os, const Rational& rat)
{
os << rat._p << ":" << rat._q;
return os;
}
istream& operator>> (istream& is, Rational& rat)
{
long long p, q;
is >> p >> q;
validate(p, q);
rat._p = p;
rat._q = q;
rat.simplify();
return is;
}
Rational Rational::operator+ (const Rational& rat)
{
Rational result(*this);
result += rat;
result.simplify();
return result;
}
Rational Rational::operator+ (long long num) const
{
Rational result(*this);
Rational temp(num);
result += temp;
result.simplify();
return result;
}
Rational operator+ (long long num, const Rational& rat)
{
Rational result(num);
result += rat;
result.simplify();
return result;
}
Rational Rational::operator- (const Rational& rat)
{
Rational result(*this);
result -= rat;
result.simplify();
return result;
}
Rational Rational::operator- (long long num) const
{
Rational result(*this);
Rational temp(num);
result -= temp;
result.simplify();
return result;
}
Rational operator- (long long num, const Rational& rat)
{
Rational result(num);
result -= rat;
result.simplify();
return result;
}
Rational Rational::operator* (const Rational& rat)
{
Rational result(*this);
result *= rat;
result.simplify();
return result;
}
Rational Rational::operator* (long long num) const
{
Rational result(*this);
Rational temp(num);
result *= temp;
result.simplify();
return result;
}
Rational operator* (long long num, const Rational& rat)
{
Rational result(num);
result *= rat;
result.simplify();
return result;
}
Rational Rational::operator/ (const Rational& rat)
{
Rational result(*this);
result /= rat;
result.simplify();
return result;
}
Rational Rational::operator/ (long long num) const
{
Rational result(*this);
Rational temp(num);
result /= temp;
result.simplify();
return result;
}
Rational operator/ (long long num, const Rational& rat)
{
Rational result(num);
result /= rat;
result.simplify();
return result;
}
bool Rational::operator== (const Rational& rat) const
{
bool result;
if ((this->_p == rat._p) && (this->_q == rat._q))
{
result = true;
}
else
{
result = false;
}
return result;
}
bool Rational::operator== (long long num) const
{
bool result;
Rational temp(num);
result = (*this == temp);
return result;
}
bool operator== (long long num, const Rational& rat)
{
bool result;
result = (rat == num);
return result;
}
bool Rational::operator!= (const Rational& rat) const
{
return !(*this == rat);
}
bool Rational::operator!= (long long num) const
{
return !(*this == num);
}
bool operator!= (long long num, const Rational& rat)
{
return !(num == rat);
}
bool Rational::operator> (const Rational& rat) const
{
bool result;
if ((this->_p / this->_q) > (rat._p / rat._q))
{
result = true;
}
else
{
result = false;
}
return result;
}
bool Rational::operator> (long long num) const
{
bool result;
Rational temp(num);
result = (*this > temp);
return result;
}
bool operator> (long long num, const Rational& rat)
{
bool result;
result = (rat < num);
return result;
}
bool Rational::operator< (const Rational& rat) const
{
bool result;
if (!(*this > rat) && !(*this == rat))
{
result = true;
}
else
{
result = false;
}
return result;
}
bool Rational::operator< (long long num) const
{
bool result;
Rational temp(num);
result = (*this < temp);
return result;
}
bool operator< (long long num, const Rational& rat)
{
bool result;
result = (rat > num);
return result;
}
bool Rational::operator>= (const Rational& rat) const
{
bool result;
if (!(*this < rat))
{
result = true;
}
else
{
result = false;
}
return result;
}
bool Rational::operator>= (long long num) const
{
bool result;
Rational temp(num);
result = (*this >= temp);
return result;
}
bool operator>= (long long num, const Rational& rat)
{
bool result;
result = (rat <= num);
return result;
}
bool Rational::operator<= (const Rational& rat) const
{
bool result;
if (!(*this > rat))
{
result = true;
}
else
{
result = false;
}
return result;
}
bool Rational::operator<= (long long num) const
{
bool result;
Rational temp(num);
result = (*this <= temp);
return result;
}
bool operator<= (long long num, const Rational& rat)
{
bool result;
result = (rat >= num);
return result;
}
Rational Rational::operator++ (int) // Postfix
{
Rational temp(*this);
this->_p++;
this->_q++;
return temp;
}
Rational Rational::operator-- (int) // Postfix
{
Rational temp(*this);
this->_p--;
this->_q--;
return temp;
}
Rational& Rational::operator++()
{
this->_p++;
this->_q++;
return *this;
}
Rational& Rational::operator--()
{
this->_p--;
this->_q--;
return *this;
}
Rational Rational::operator-() const
{
Rational temp(-(this->_p), (this->_q));
return temp;
}
Rational Rational::operator+() const
{
Rational temp(+(this->_p), +(this->_q));
return temp;
}
Rational Rational::pow (unsigned exp) const
{
Rational result(*this);
Rational temp(*this);
if (exp == 0)
{
result = 1;
}
else
{
for (unsigned i = 1; i < exp; i++)
{
result *= temp;
}
}
return result;
}
Rational Rational::inverse() const
{
Rational temp(this->_q, this->_p);
return temp;
}
void validate(long long p, long long q)
{
p++; // Supress error for unused value. Decided to keep value in parameter list to maintain clarity.
if (q == 0)
{
throw "Zero Denominator";
}
}
int gcd(long long p, long long q)
{
// Euclid's Algorithm
if (q == 0)
{
return p;
}
return gcd (q, p%q);
}
++
and--
operators are implemented wrongly. You don't add1
to a rational number by incrementing both numerator and denominator. \$\endgroup\$namespace std
in the header" - nor me; I'd hope for the teaching profession to set an admirable example. Disappointed again... \$\endgroup\$main()
that verifies that (e.g.)2/4
==1/2
and so on for all your implementation would help ensure the code is correct and would document your understanding of the requirements. \$\endgroup\$