xoreos  0.0.5
rational.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 /* Based on ScummVM (<http://scummvm.org>) code, which is released
26  * under the terms of version 2 or later of the GNU General Public
27  * License.
28  *
29  * The original copyright note in ScummVM reads as follows:
30  *
31  * ScummVM is the legal property of its developers, whose names
32  * are too numerous to list here. Please refer to the COPYRIGHT
33  * file distributed with this source distribution.
34  *
35  * This program is free software; you can redistribute it and/or
36  * modify it under the terms of the GNU General Public License
37  * as published by the Free Software Foundation; either version 2
38  * of the License, or (at your option) any later version.
39  *
40  * This program is distributed in the hope that it will be useful,
41  * but WITHOUT ANY WARRANTY; without even the implied warranty of
42  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43  * GNU General Public License for more details.
44  *
45  * You should have received a copy of the GNU General Public License
46  * along with this program; if not, write to the Free Software
47  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
48  */
49 
50 #include "src/common/algorithm.h"
51 #include "src/common/error.h"
52 #include "src/common/rational.h"
53 
54 namespace Common {
55 
57  _num = 1;
58  _denom = 1;
59 }
60 
62  _num = num;
63  _denom = 1;
64 }
65 
66 Rational::Rational(int num, int denom) {
67  if (denom == 0)
68  throw Exception("Denominator cannot be 0");
69 
70  if (denom > 0) {
71  _num = num;
72  _denom = denom;
73  } else {
74  _num = -num;
75  _denom = -denom;
76  }
77 
78  cancel();
79 }
80 
82  // Cancel the fraction by dividing both the num and the denom
83  // by their greatest common divisor.
84 
85  const int gcd = Common::gcd(_num, _denom);
86 
87  _num /= gcd;
88  _denom /= gcd;
89 }
90 
92  _num = right._num;
93  _denom = right._denom;
94 
95  return *this;
96 }
97 
99  _num = right;
100  _denom = 1;
101 
102  return *this;
103 }
104 
106  // Cancel common factors to avoid unnecessary overflow.
107  // Note that the result is *not* always normalized.
108  const int gcd = Common::gcd(_denom, right._denom);
109 
110  _num = _num * (right._denom / gcd);
111  _denom = _denom / gcd;
112  _num += right._num * _denom;
113  _denom *= right._denom;
114 
115  cancel();
116 
117  return *this;
118 }
119 
121  // Cancel common factors to avoid unnecessary overflow.
122  // Note that the result is *not* always normalized.
123  const int gcd = Common::gcd(_denom, right._denom);
124 
125  _num = _num * (right._denom / gcd);
126  _denom = _denom / gcd;
127  _num -= right._num * _denom;
128  _denom *= right._denom;
129 
130  cancel();
131 
132  return *this;
133 }
134 
136  // Cross-cancel to avoid unnecessary overflow;
137  // the result then is automatically normalized
138  const int gcd1 = gcd(_num, right._denom);
139  const int gcd2 = gcd(right._num, _denom);
140 
141  _num = (_num / gcd1) * (right._num / gcd2);
142  _denom = (_denom / gcd2) * (right._denom / gcd1);
143 
144  return *this;
145 }
146 
148  return *this *= right.getInverse();
149 }
150 
152  return *this += Rational(right);
153 }
154 
156  return *this -= Rational(right);
157 }
158 
160  return *this *= Rational(right);
161 }
162 
164  return *this /= Rational(right);
165 }
166 
168  return Rational(-_num, _denom);
169 }
170 
171 const Rational Rational::operator+(const Rational &right) const {
172  Rational tmp = *this;
173  tmp += right;
174  return tmp;
175 }
176 
177 const Rational Rational::operator-(const Rational &right) const {
178  Rational tmp = *this;
179  tmp -= right;
180  return tmp;
181 }
182 
183 const Rational Rational::operator*(const Rational &right) const {
184  Rational tmp = *this;
185  tmp *= right;
186  return tmp;
187 }
188 
189 const Rational Rational::operator/(const Rational &right) const {
190  Rational tmp = *this;
191  tmp /= right;
192  return tmp;
193 }
194 
195 const Rational Rational::operator+(int right) const {
196  Rational tmp = *this;
197  tmp += right;
198  return tmp;
199 }
200 
201 const Rational Rational::operator-(int right) const {
202  Rational tmp = *this;
203  tmp -= right;
204  return tmp;
205 }
206 
207 const Rational Rational::operator*(int right) const {
208  Rational tmp = *this;
209  tmp *= right;
210  return tmp;
211 }
212 
213 const Rational Rational::operator/(int right) const {
214  Rational tmp = *this;
215  tmp /= right;
216  return tmp;
217 }
218 
219 bool Rational::operator==(const Rational &right) const {
220  return (_num == right._num) && (_denom == right._denom);
221 }
222 
223 bool Rational::operator!=(const Rational &right) const {
224  return (_num != right._num) || (_denom != right._denom);
225 }
226 
227 bool Rational::operator>(const Rational &right) const {
228  return (_num * right._denom) > (right._num * _denom);
229 }
230 
231 bool Rational::operator<(const Rational &right) const {
232  return (_num * right._denom) < (right._num * _denom);
233 }
234 
235 bool Rational::operator>=(const Rational &right) const {
236  return (_num * right._denom) >= (right._num * _denom);
237 }
238 
239 bool Rational::operator<=(const Rational &right) const {
240  return (_num * right._denom) <= (right._num * _denom);
241 }
242 
243 bool Rational::operator==(int right) const {
244  return (_denom == 1) && (_num == right);
245 }
246 
247 bool Rational::operator!=(int right) const {
248  return (_denom != 1) || (_num != right);
249 }
250 
251 bool Rational::operator>(int right) const {
252  return *this > Rational(right, 1);
253 }
254 
255 bool Rational::operator<(int right) const {
256  return *this < Rational(right, 1);
257 }
258 
259 bool Rational::operator>=(int right) const {
260  return *this >= Rational(right, 1);
261 }
262 
263 bool Rational::operator<=(int right) const {
264  return *this <= Rational(right, 1);
265 }
266 
268  if (_num == 0)
269  throw Exception("Denominator cannot be 0");
270 
271  std::swap(_num, _denom);
272 
273  if (_denom < 0) {
274  _denom = -_denom;
275  _num = -_num;
276  }
277 }
278 
280  Rational inverse = *this;
281 
282  inverse.invert();
283 
284  return inverse;
285 }
286 
287 int Rational::toInt() const {
288  return _num / _denom;
289 }
290 
291 double Rational::toDouble() const {
292  return ((double)_num) / ((double)_denom);
293 }
294 
295 const Rational operator+(int left, const Rational &right) {
296  Rational tmp(left);
297  tmp += right;
298  return tmp;
299 }
300 
301 const Rational operator-(int left, const Rational &right) {
302  Rational tmp(left);
303  tmp -= right;
304  return tmp;
305 }
306 
307 const Rational operator*(int left, const Rational &right) {
308  Rational tmp(left);
309  tmp *= right;
310  return tmp;
311 }
312 
313 const Rational operator/(int left, const Rational &right) {
314  Rational tmp(left);
315  tmp /= right;
316  return tmp;
317 }
318 
319 bool operator==(int left, const Rational &right) {
320  return right == left;
321 }
322 
323 bool operator!=(int left, const Rational &right) {
324  return right != left;
325 }
326 
327 bool operator>(int left, const Rational &right) {
328  return right < left;
329 }
330 
331 bool operator<(int left, const Rational &right) {
332  return right > left;
333 }
334 
335 bool operator>=(int left, const Rational &right) {
336  return right <= left;
337 }
338 
339 bool operator<=(int left, const Rational &right) {
340  return right >= left;
341 }
342 
343 } // End of namespace Common
T gcd(T a, T b)
Euclid&#39;s algorithm to compute the greatest common divisor.
Definition: algorithm.h:59
Rational & operator=(const Rational &right)
Definition: rational.cpp:91
Definition: 2dafile.h:39
A simple rational class that holds fractions.
Definition: rational.h:56
const Rational operator*(const Rational &right) const
Definition: rational.cpp:183
bool operator!=(const Rational &right) const
Definition: rational.cpp:223
Supplemental algorithms.
Rational & operator/=(const Rational &right)
Definition: rational.cpp:147
int toInt() const
Definition: rational.cpp:287
Rational & operator-=(const Rational &right)
Definition: rational.cpp:120
const Rational operator-(int left, const Rational &right)
Definition: rational.cpp:301
bool operator<=(const Rational &right) const
Definition: rational.cpp:239
bool operator<(int left, const Rational &right)
Definition: rational.cpp:331
double toDouble() const
Definition: rational.cpp:291
const Rational operator*(int left, const Rational &right)
Definition: rational.cpp:307
Basic exceptions to throw.
const Rational operator/(const Rational &right) const
Definition: rational.cpp:189
bool operator<=(int left, const Rational &right)
Definition: rational.cpp:339
bool operator>(const Rational &right) const
Definition: rational.cpp:227
bool operator>=(int left, const Rational &right)
Definition: rational.cpp:335
bool operator==(const Rational &right) const
Definition: rational.cpp:219
StackException Exception
Definition: error.h:59
Rational & operator+=(const Rational &right)
Definition: rational.cpp:105
const Rational operator+(const Rational &right) const
Definition: rational.cpp:171
bool operator==(int left, const Rational &right)
Definition: rational.cpp:319
static glm::mat4 inverse(const glm::mat4 &m)
Definition: graphics.cpp:1363
const Rational operator/(int left, const Rational &right)
Definition: rational.cpp:313
bool operator>(int left, const Rational &right)
Definition: rational.cpp:327
Rational & operator*=(const Rational &right)
Definition: rational.cpp:135
bool operator!=(int left, const Rational &right)
Definition: rational.cpp:323
Rational number implementation.
bool operator>=(const Rational &right) const
Definition: rational.cpp:235
const Rational operator+(int left, const Rational &right)
Definition: rational.cpp:295
bool operator<(const Rational &right) const
Definition: rational.cpp:231
Rational getInverse() const
Definition: rational.cpp:279
const Rational operator-() const
Definition: rational.cpp:167