#include #include #include #include #include class Fraction { int _numerator; int _denominator; void _simplify() { auto common = std::gcd(_numerator, _denominator); _numerator /= common; _denominator /= common; } public: Fraction(int num = 0, int den = 1) : _numerator(num), _denominator(den) { assert(_denominator != 0); _simplify(); //std::cout << "Created fraction " << *this << std::endl; } // Fraction(Fraction const &a) // { // _numerator = a._numerator; // _denominator = a._denominator; // std::cout << "Copied fraction " << *this << std::endl; // } int numerator() const { return _numerator; } int denominator() const { return _denominator; } operator double() const { return static_cast(_numerator)/_denominator; } explicit operator std::string() const { return std::to_string(_numerator) + "/" + std::to_string(_denominator); } friend Fraction operator+(Fraction const &a, Fraction const &b); friend Fraction operator-(Fraction const &a, Fraction const &b); friend Fraction operator*(Fraction const &a, Fraction const &b); friend Fraction operator/(Fraction const &a, Fraction const &b); friend bool operator==(Fraction const &a, Fraction const &b) { return a._numerator == b._numerator && a._denominator == b._denominator; } friend bool operator!=(Fraction const &a, Fraction const &b) { return !(a == b); } friend bool operator<(Fraction const &a, Fraction const &b); friend bool operator>=(Fraction const &a, Fraction const &b) { return !(a < b); } friend bool operator>(Fraction const &a, Fraction const &b); friend bool operator<=(Fraction const &a, Fraction const &b) { return !(a > b); } Fraction &operator++() { _numerator += _denominator; return *this; } Fraction &operator--() { _numerator -= _denominator; return *this; } Fraction operator++(int) { auto old = *this; ++(*this); return old; } Fraction operator--(int) { auto old = *this; --(*this); return old; } Fraction &operator=(Fraction const &a) { if (&a != this) { _numerator = a._numerator; _denominator = a._denominator; } return *this; } Fraction &operator+=(Fraction const &a); Fraction &operator-=(Fraction const &a); Fraction &operator*=(Fraction const &a); Fraction &operator/=(Fraction const &a); friend std::ostream &operator<<(std::ostream &os, Fraction const &a) { os << std::string(a); return os; } // ~Fraction() // { // std::cout << "Fraction with value " << *this << " is gone\n"; // } }; Fraction operator+(Fraction const &a, Fraction const &b) { auto num = a._numerator * b._denominator + a._denominator * b._numerator; auto den = a._denominator * b._denominator; return Fraction{num, den}; } Fraction operator-(Fraction const &a, Fraction const &b) { auto num = a._numerator * b._denominator - a._denominator * b._numerator; auto den = a._denominator * b._denominator; return Fraction{num, den}; } Fraction operator*(Fraction const &a, Fraction const &b) { auto num = a._numerator * b._numerator; auto den = a._denominator * b._denominator; return Fraction(num, den); } Fraction operator/(Fraction const &a, Fraction const &b) { auto num = a._numerator * b._denominator; auto den = a._denominator * b._numerator; return Fraction{num, den}; } bool operator<(Fraction const &a, Fraction const &b) { return a._numerator * b._denominator < a._denominator * b._numerator; } bool operator>(Fraction const &a, Fraction const &b) { return a._numerator * b._denominator > a._denominator * b._numerator; } Fraction &Fraction::operator+=(Fraction const &a) { auto sum = *this + a; this->_numerator = sum._numerator; this->_denominator = sum._denominator; return *this; } Fraction &Fraction::operator-=(Fraction const &a) { auto diff = *this - a; this->_numerator = diff._numerator; this->_denominator = diff._denominator; return *this; } Fraction &Fraction::operator*=(Fraction const &a) { auto prod = *this * a; this->_numerator = prod._numerator; this->_denominator = prod._denominator; return *this; } Fraction &Fraction::operator/=(Fraction const &a) { auto div = *this / a; this->_numerator = div._numerator; this->_denominator = div._denominator; return *this; } void talk_about_fraction(Fraction f) { std::cout << "I have a fraction with numerator " << f.numerator() << " and denominator " << f.denominator() << std::endl; } void talk_about_double(double x) { std::cout << "I have a double with value " << x << std::endl; } void talk_about_int(int n) { std::cout << "I have an int with value " << n << std::endl; } void talk_about_string(std::string s) { std::cout << "I have a string with content " << s << std::endl; } int main(int, char *[]) { std::vector values = { Fraction{1, 1}, Fraction{2, 3}, Fraction{1, 2}, Fraction{2, 4}, Fraction{13, 7}, Fraction{3} }; std::cout << "Values: "; for (auto const &f: values) { std::cout << f << " "; } std::cout << std::endl; std::cout << "Again, here is what I have:\n"; for (auto const &f: values) { talk_about_fraction(f); talk_about_double(f); talk_about_int(f); talk_about_string(std::string(f)); } std::cout << "Also this: "; talk_about_fraction(42); size_t N = values.size(); std::cout << "Adding thing...\n"; for (size_t i = 0; i < N-1; ++i) { for (size_t j = i+1; j < N; ++j) { std::cout << values[i] << " + " << values[j] << " = " << values[i] + values[j] << std::endl; } } std::cout << "Dividing things...\n"; for (size_t i = 0; i < N-1; ++i) { for (size_t j = i+1; j < N; ++j) { std::cout << values[i] << " / " << values[j] << " = " << values[i] / values[j] << std::endl; } } Fraction product{1}; for (auto const &f: values) { product *= f; } std::cout << "Multiplying everything gives: " << product << std::endl; ; std::cout << "Comparing things...\n"; for (size_t i = 0; i < N-1; ++i) { for (size_t j = i+1; j < N; ++j) { if (values[i] != values[j]) { std::cout << values[i] << " is "; if (values[i] < values[j]) { std::cout << "less"; } else { std::cout << "greater"; } std::cout << " than " << values[j] << std::endl; } } } std::cout << "Counting up...\n"; for (auto &f: values) { std::cout << ++f << ", " << ++f << ", " << ++f << std::endl; } std::cout << "Counting down...\n"; for (auto &f: values) { std::cout << --f << ", " << --f << ", " << --f << std::endl; } std::cout << "Counting up another way...\n"; for (auto &f: values) { std::cout << f++ << ", " << f++ << ", " << f++ << std::endl; } std::cout << "Counting down another way...\n"; for (auto &f: values) { std::cout << f-- << ", " << f-- << ", " << f-- << std::endl; } return 0; }