fraction.hpp
#ifndef FRACTION_H
#define FRACTION_H
#include <iostream>
class fraction {
private:
int _numerator, _denominator;
int gcd(const int &, const int &) const;
// If you don't need this method, just ignore it.
void simp();
// To get the lowest terms.
public:
fraction(const int & = 0, const int & = 1);
// The numerator and the denominator
// fraction(5) = 5/1 = 5 :)
fraction(const fraction &);
// copy constructor
void operator=(const fraction &);
// You must know the meaning of +-*/, don't you ?
fraction operator+(const fraction &) const;
fraction operator-(const fraction &) const;
fraction operator*(const fraction &) const;
fraction operator/(const fraction &) const;
void operator+=(const fraction &);
void operator-=(const fraction &);
void operator*=(const fraction &);
void operator/=(const fraction &);
// Comparison operators
bool operator==(const fraction &) const;
bool operator!=(const fraction &) const;
bool operator<(const fraction &) const;
bool operator>(const fraction &) const;
bool operator<=(const fraction &) const;
bool operator>=(const fraction &) const;
friend std::istream & operator>>(std::istream &, fraction &);
// Input Format: two integers with a space in it
// "a b" is correct. Not "a/b"
friend std::ostream & operator<<(std::ostream &, const fraction &);
// Normally you should output "a/b" without any space and LF
// Sometims you may output a single integer (Why? Guess XD)
// If it is not a number (den = 0), output "NaN"
};
#endif
fraction.cpp
#include "fraction.hpp"
#include <iostream>
#include <cmath>
int fraction::gcd(const int &a, const int &b) const {
if (a == 0||b == 0) {
if (a == 0)
return b;
return a;
}
if (a%b == 0) {
return b;
}
if (b%a == 0) {
return a;
}
if (abs(a) < abs(b)) {
return gcd(b % a, a);
}
else {
return gcd(a % b, b);
}
}
void fraction::simp() {
if (_numerator == 0 && _denominator == 0)
return;
int p = gcd(_numerator, _denominator);
_numerator /= p;
_denominator /= p;
if (_denominator < 0&&_numerator>0|| _denominator > 0 && _numerator<0) {
_numerator = -abs(_numerator);
_denominator = abs(_denominator);
}
}
fraction::fraction(const int &a, const int &b) {
_numerator = a;
_denominator = b;
simp();
}
fraction::fraction(const fraction &x) {
_numerator = x._numerator;
_denominator = x._denominator;
simp();
}
void fraction::operator=(const fraction &x) {
_numerator = x._numerator;
_denominator = x._denominator;
}
fraction fraction::operator+(const fraction &x) const {
fraction tp(_numerator, _denominator);
tp._denominator = x._denominator*tp._denominator;
tp._numerator = tp._numerator*x._denominator + x._numerator*_denominator;
tp.simp();
return tp;
}
fraction fraction::operator-(const fraction &x) const {
int p = gcd(x._denominator, _denominator);
fraction tp(_numerator, _denominator);
tp._denominator = x._denominator/p*(tp._denominator);
tp._numerator = x._denominator/p*tp._numerator - (_denominator/p)*x._numerator;
tp.simp();
return tp;
}
fraction fraction::operator*(const fraction &x) const {
fraction tp(_numerator, _denominator);
fraction xp(x);
int p1 = gcd(_numerator, x._denominator);
int p2 = gcd(_denominator, x._numerator);
tp._numerator /= p1;
xp._denominator /= p1;
tp._denominator /= p2;
xp._numerator /= p2;
tp._denominator = xp._denominator*tp._denominator;
tp._numerator = tp._numerator*xp._numerator;
tp.simp();
return tp;
}
fraction fraction::operator/(const fraction &x) const {
fraction tp(_numerator, _denominator);
fraction xp(x);
int p1 = gcd(_numerator, x._numerator);
int p2 = gcd(_denominator, x._denominator);
tp._numerator /= p1;
xp._denominator /= p2;
tp._denominator /= p2;
xp._numerator /= p1;
tp._denominator = tp._denominator*xp._numerator;
tp._numerator = tp._numerator*xp._denominator;
tp.simp();
return tp;
}
void fraction::operator+=(const fraction &x) {
(*this) = x + (*this);
}
void fraction::operator-=(const fraction &x) {
(*this) = (*this)-x;
}
void fraction::operator*=(const fraction &x) {
(*this) = x * (*this);
}
void fraction::operator/=(const fraction &x) {
(*this) = (*this)/x;
}
bool fraction::operator==(const fraction &x) const {
if (_denominator == 0 && x._denominator == 0)
return 1;
if (_numerator == x._numerator&&_denominator == x._denominator)
return 1;
return 0;
}
bool fraction::operator!=(const fraction &x) const {
if (_denominator == 0 && x._denominator == 0)
return 0;
if (_numerator == x._numerator&&_denominator == x._denominator)
return 0;
return 1;
}
bool fraction::operator<(const fraction &x) const {
if (_denominator == 0 && x._denominator == 0)
return 0;
fraction tp(_numerator, _denominator);
tp._denominator = x._denominator*tp._denominator;
tp._numerator = tp._numerator*x._denominator - x._numerator*_denominator;
tp.simp();
if (tp._numerator < 0)
return 1;
return 0;
}
bool fraction::operator>(const fraction &x) const {
if (_denominator == 0 && x._denominator == 0)
return 0;
fraction tp(_numerator, _denominator);
tp._denominator = x._denominator*tp._denominator;
tp._numerator = tp._numerator*x._denominator - x._numerator*_denominator;
tp.simp();
if (tp._numerator < 0)
return 0;
return 1;
}
bool fraction::operator<=(const fraction &x) const {
return !((*this) > x);
}
bool fraction::operator>=(const fraction &x) const {
return !((*this) < x);
}
std::istream & operator>>(std::istream &in, fraction &x) {
in >> x._numerator >> x._denominator;
x.simp();
return in;
}
std::ostream & operator<<(std::ostream &out, const fraction &x) {
if (x._denominator == 0)
out << "NaN";
else if (x._denominator == 1)
out << x._numerator;
else
out << x._numerator << "/" << x._denominator;
return out;
}