Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- using namespace std;
- namespace NumberAlgorithms
- {
- template <class T> T Max(const T& a, const T& b) { return (a > b) ? a : b; }
- template <class T> T Min(const T& a, const T& b) { return (a < b) ? a : b; }
- template <class T> T GreatestCommonFactor(const T& a, const T& b)
- {
- T gcf = 1, max = Min(a, b);
- for (T i = 2; i < max; i++)
- if (a % i + b % i == 0)
- gcf = i;
- return gcf;
- }
- template <class T> T LeastCommonMultiple(const T& a, const T& b)
- {
- T max = a * b;
- for (T i = Min(a, b); i < max; i++;)
- if (i % a + i % b == 0)
- return i;
- }
- };
- // Fraction SHOULD be a struct, as it is a data type, and doesn't function
- // with other objects. Other objects use it, but it doesn't depend on anything.
- // T must be an number type (representing any real rational number)
- template <class T> // It is not possible to use constraints in c++
- class Fraction // So we have to assume that the user will use an integral type
- {
- private:
- T Numerator, Denominator;
- void Reduce()
- {
- T gcf = NumberAlgorithms::GreatestCommonFactor(Numerator, Denominator);
- Numerator /= gcf;
- Denominator /= gcf;
- if (Denominator < 0)
- {
- Numerator *= -1;
- Denominator *= -1;
- }
- }
- public:
- Fraction() : Numerator(1), Denominator(1) { }
- Fraction(T n) : Numerator(n) { SetDenominator(1); }
- Fraction(T n, T d) : Numerator(n) { SetDenominator(d); }
- void SetNumerator(const T& value)
- {
- Numerator = value;
- Reduce();
- }
- T GetNumerator() const { return Numerator; }
- void SetDenominator(const T& value)
- {
- if (value == 0) throw std::exception("Divide by zero");
- Denominator = value;
- Reduce();
- }
- T GetDenominator() const { return Denominator; }
- friend ostream& operator<<(const ostream& output, const Fraction<T> value);
- friend istream& operator>>(const istream& input, Fraction<T> value);
- friend Fraction<T> operator+(const Fraction<T>& left, const Fraction<T>& right);
- friend Fraction<T> operator-(const Fraction<T>& left, const Fraction<T>& right);
- friend Fraction<T> operator*(const Fraction<T>& left, const Fraction<T>& right);
- friend Fraction<T> operator/(const Fraction<T>& left, const Fraction<T>& right);
- bool operator<(const Fraction<T>& right) const
- {
- T a = GetNumerator(), b = GetDenominator(), c = right.GetNumerator(), d = right.GetDenominator();
- return (a * d < b * c);
- }
- bool operator>(const Fraction<T>& right) const
- {
- T a = GetNumerator(), b = GetDenominator(), c = right.GetNumerator(), d = right.GetDenominator();
- return (a * d > b * c);
- }
- bool operator<=(const Fraction<T>& right) const
- {
- T a = GetNumerator(), b = GetDenominator(), c = right.GetNumerator(), d = right.GetDenominator();
- return (a * d <= b * c);
- }
- bool operator>=(const Fraction<T>& right) const
- {
- T a = GetNumerator(), b = GetDenominator(), c = right.GetNumerator(), d = right.GetDenominator();
- return (a * d >= b * c);
- }
- bool operator==(const Fraction<T>& right) const
- {
- T a = GetNumerator(), b = GetDenominator(), c = right.GetNumerator(), d = right.GetDenominator();
- return (a * d == b * c);
- }
- bool operator!=(const Fraction<T>& right) const
- {
- T a = GetNumerator(), b = GetDenominator(), c = right.GetNumerator(), d = right.GetDenominator();
- return (a * d != b * c);
- }
- };
- template <class T> Fraction<T> operator+(Fraction<T> const& left, Fraction<T> const& right)
- {
- T a = left.GetNumerator(), b = left.GetDenominator(), c = right.GetNumerator(), d = right.GetDenominator(), x;
- using NumberAlgorithms;
- x = LeastCommonMultiple<T>(b, d);
- a *= x / d;
- b *= x / d;
- c *= x / b;
- d *= x / b;
- return Fraction<T>(a + b, c);
- }
- template <class T> Fraction<T> operator-(Fraction<T> const& left, Fraction<T> const& right)
- {
- T a = left.GetNumerator(), b = left.GetDenominator(), c = right.GetNumerator(), d = right.GetDenominator(), x;
- using NumberAlgorithms;
- x = LeastCommonMultiple<T>(b, d);
- a *= x / d;
- b *= x / d;
- c *= x / b;
- d *= x / b;
- return Fraction<T>(a - b, c);
- }
- template <class T> Fraction<T> operator*(Fraction<T> const& left, Fraction<T> const& right)
- {
- T a = left.GetNumerator(), b = left.GetDenominator(), c = right.GetNumerator(), d = right.GetDenominator();
- if (b == 0 || d == 0) throw exception("Divide by zero");
- return Fraction<T>(a * c, b * d);
- }
- template <class T> Fraction<T> operator/(Fraction<T> const& left, Fraction<T> const& right)
- {
- T a = left.GetNumerator(), b = left.GetDenominator(), c = right.GetNumerator(), d = right.GetDenominator();
- if (c == 0 || d == 0) throw new exception("Divide by zero");
- return Fraction<T>(a * d, b * c);
- }
- template <class T> ostream& operator<<(const ostream& output, const Fraction<T>& value)
- {
- output << value.Numerator << '/' << value.Denominator;
- return output;
- }
- template <class T> istream& operator>>(const istream& input, Fraction<T>& value)
- {
- T n, d, char seperator;
- cin >> n >> seperator >> d;
- value.SetNumerator(n);
- value.SetDenominator(d);
- return input;
- }
- bool Test()
- {
- char answer;
- Fraction<int> test1, test2, test3(10);
- int a, b;
- cout << endl << "Please enter two whole numbers. ex: a b : ";
- cin >> a >> b;
- test1 = Fraction<int>(a, b);
- cout << endl << "Please enter two whole numbers. ex: a/b : ";
- cin >> test2;
- // Display the three values to test cout
- cout << "\nTest1 equals " << test1;
- cout << "\nTest2 equals " << test2;
- cout << "\nTest3 equals " << test3;
- // Test our operators
- cout << "\nTest1 * Test2 equals " << test1*test2;
- cout << "\nTest1 / Test3 equals " << test1/test3;
- cout << "\nTest2 + Test3 equals " << test2+test3;
- cout << "\nTest3 - Test1 equals " << test3-test1;
- if (test1 == test2)
- cout << "\nTest1 is equal to Test2";
- if (test1 < test2)
- cout << "\nTest1 is less than Test2";
- cout << "Would you like to test again? ";
- cin >> answer;
- return answer == 'Y' || answer == 'y';
- }
- int main()
- {
- cout << endl << "Project 11-5" << endl << endl
- << "Testing the Fraction class." << endl
- << "The fraction class stores a numerator and denominator digit (n/d)" << endl
- << "Let the testing commence!" << endl;
- while (Test()) ;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement