Rings for MAT 685
Mathematical ring implementation to demonstrate templates and inheritance
rational.hpp
1 #ifndef __RATIONAL_HPP_
2 #define __RATIONAL_HPP_
3 
4 #include "../gcd/gcd_template.hpp"
5 #include "rings.hpp"
6 #include "integer.hpp"
7 
8 namespace Rings {
9 
15 template<typename T>
16 class Rational : public Field_Element {
17 
18 protected:
19 
21  T num;
23  T den;
24 
26  void simplify();
27 
28 public:
29 
33 
35  Rational<T>();
37  Rational<T>(T);
41  Rational<T>(T, T);
43  Rational<T>(const Integer<T> &);
45  Rational<T>(const Rational<T> &);
46 
47  virtual bool is_one() const override;
48  virtual bool is_zero() const override;
49 
50  virtual Ring_Element & operator + (const Ring_Element &) const override;
51  virtual Ring_Element & operator - (const Ring_Element &) const override;
52  virtual Ring_Element & operator * (const Ring_Element &) const override;
53  virtual Field_Element & operator / (const Field_Element &) const override;
54 
56  const Rational<T> & operator = (const Ring_Element &);
57 
58  virtual bool operator == (const Ring_Element &) const override;
59  virtual bool operator != (const Ring_Element &) const override;
60 
62  virtual Field_Element & inverse() const override;
63 
65  T get_numerator() const;
67  T get_denominator() const;
68 
69 };
70 
71 template<typename T>
73  if (num == 0)
74  den = 1;
75  else {
76  T d = gcd<T>(num, den);
77  num /= d;
78  den /= d;
79  }
80 }
81 
82 template<typename T>
84 
85 template<typename T>
86 Rational<T>::Rational(T integer) : num(integer), den(1) { }
87 
88 template<typename T>
89 Rational<T>::Rational(T numerator, T denominator)
90  : num(numerator), den(denominator)
91 {
92  simplify();
93 }
94 
95 template<typename T>
96 Rational<T>::Rational(const Integer<T> & other) : num(other.get_value()), den(1)
97 { }
98 
99 template<typename T>
100 Rational<T>::Rational(const Rational<T> & other) : num(other.num), den(other.den)
101 { }
102 
103 template<typename T>
104 bool Rational<T>::is_one() const { return num == den; }
105 
106 template<typename T>
107 bool Rational<T>::is_zero() const { return num == 0; }
108 
109 template<typename T>
111  static Rational<T> result;
112  result = dynamic_cast<const Rational<T> &>(other);
113  result.num = result.num * den + num * result.den;
114  result.den *= den;
115  result.simplify();
116  return result;
117 }
118 
119 template<typename T>
121  static Rational<T> result;
122  result = dynamic_cast<const Rational<T> &>(other);
123  result.num = - result.num * den + num * result.den;
124  result.den *= den;
125  result.simplify();
126  return result;
127 }
128 
129 template<typename T>
131  static Rational<T> result;
132  result = dynamic_cast<const Rational<T> &>(other);
133  result.num *= num;
134  result.den *= den;
135  result.simplify();
136  return result;
137 }
138 
139 template<typename T>
141  static Rational<T> result;
142  result.num = num;
143  result.den = den;
144  result.num *= dynamic_cast<const Rational<T> &>(other).num;
145  result.den *= dynamic_cast<const Rational<T> &>(other).den;
146  result.simplify();
147  return result;
148 }
149 
150 template<typename T>
152  if (*this != o) {
153  const Rational<T> & other = dynamic_cast<const Rational<T> &>(o);
154  num = other.num;
155  den = other.den;
156  }
157  return *this;
158 }
159 
160 template<typename T>
162  const Rational<T> & other = dynamic_cast<const Rational<T> &>(o);
163  return num == other.num and den == other.den;
164 }
165 
166 template<typename T>
168  const Rational<T> & other = dynamic_cast<const Rational<T> &>(o);
169  return num != other.num or den != other.den;
170 }
171 
172 template<typename T>
174  static Rational<T> result(den, num);
175  return result;
176 }
177 
178 template<typename T>
179 T Rational<T>::get_numerator() const { return num; }
180 
181 template<typename T>
182 T Rational<T>::get_denominator() const { return den; }
183 
188 template<typename T>
189 ostream & operator << (ostream & os, const Rational<T> & r) {
190  os << r.get_numerator();
191  if (r.get_denominator() != 1)
192  os << " / " << r.get_denominator();
193  return os;
194 }
195 
196 }
197 
198 
199 #endif
T den
the denominator
Definition: rational.hpp:23
virtual Ring_Element & operator-(const Ring_Element &) const override
subtraction: other element should be of same type, use a cast
Definition: rational.hpp:120
virtual bool is_zero() const override
should be True iff element is additive identity
Definition: rational.hpp:107
a field is an integral domain whose nonzero elements have inverses
Definition: rings.hpp:63
virtual bool is_cancellable() const override
integral domains are commutative rings without zero divisors, so the element should be cancellable (s...
Definition: rings.hpp:59
virtual Field_Element & inverse() const override
returns reciprocal
Definition: rational.hpp:173
a type for rational numbers
Definition: rational.hpp:16
virtual Field_Element & operator/(const Field_Element &) const override
division: other element should be of same type, use a cast
Definition: rational.hpp:140
Definition: integer.hpp:6
virtual bool is_one() const override
should be True iff element is multiplicative identity
Definition: rational.hpp:104
virtual Ring_Element & operator+(const Ring_Element &) const override
addition: other element should be of same type, use a cast
Definition: rational.hpp:110
encapsulates integers under the Ring_Element rubric
Definition: integer.hpp:17
Rational()
initializes to 0
Definition: rational.hpp:83
virtual bool is_commutative() const override
Duh.
Definition: rings.hpp:42
const Rational< T > & operator=(const Ring_Element &)
assignment operator may be needed
Definition: rational.hpp:151
a class for elements with the capabilities of ring arithmetic
Definition: rings.hpp:9
virtual bool has_inverse() const override
fields are integral domains where nonzero elements have inverses
Definition: rings.hpp:68
T get_numerator() const
returns the numerator
Definition: rational.hpp:179
void simplify()
uses the gcd to reduce num and denom (if necessary)
Definition: rational.hpp:72
virtual Ring_Element & operator*(const Ring_Element &) const override
multiplicationL other element should be of same type, use a cast
Definition: rational.hpp:130
virtual bool operator!=(const Ring_Element &) const override
comparison: other element has different value
Definition: rational.hpp:167
T get_denominator() const
returns the denominator
Definition: rational.hpp:182
T num
the numerator
Definition: rational.hpp:21
virtual bool operator==(const Ring_Element &) const override
comparison: other element has same value
Definition: rational.hpp:161