ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

rational.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/debug.h"
00024 #include "common/rational.h"
00025 #include "common/util.h"
00026 #include "common/algorithm.h"
00027 
00028 namespace Common {
00029 
00030 Rational::Rational() {
00031     _num   = 1;
00032     _denom = 1;
00033 }
00034 
00035 Rational::Rational(int num) {
00036     _num   = num;
00037     _denom = 1;
00038 }
00039 
00040 Rational::Rational(int num, int denom) {
00041     assert(denom != 0);
00042 
00043     if (denom > 0) {
00044         _num   = num;
00045         _denom = denom;
00046     } else {
00047         _num   = -num;
00048         _denom = -denom;
00049     }
00050 
00051     cancel();
00052 }
00053 
00054 void Rational::cancel() {
00055     // Cancel the fraction by dividing both the num and the denom
00056     // by their greatest common divisor.
00057 
00058     const int gcd = Common::gcd(_num, _denom);
00059 
00060     _num   /= gcd;
00061     _denom /= gcd;
00062 }
00063 
00064 Rational &Rational::operator=(const Rational &right) {
00065     _num   = right._num;
00066     _denom = right._denom;
00067 
00068     return *this;
00069 }
00070 
00071 Rational &Rational::operator=(int right) {
00072     _num   = right;
00073     _denom = 1;
00074 
00075     return *this;
00076 }
00077 
00078 Rational &Rational::operator+=(const Rational &right) {
00079     // Cancel common factors to avoid unnecessary overflow.
00080     // Note that the result is *not* always normalized.
00081     const int gcd = Common::gcd(_denom, right._denom);
00082 
00083     _num    = _num * (right._denom / gcd);
00084     _denom  = _denom / gcd;
00085     _num   += right._num * _denom;
00086     _denom *= right._denom;
00087 
00088     cancel();
00089 
00090     return *this;
00091 }
00092 
00093 Rational &Rational::operator-=(const Rational &right) {
00094     // Cancel common factors to avoid unnecessary overflow.
00095     // Note that the result is *not* always normalized.
00096     const int gcd = Common::gcd(_denom, right._denom);
00097 
00098     _num    = _num * (right._denom / gcd);
00099     _denom  = _denom / gcd;
00100     _num   -= right._num * _denom;
00101     _denom *= right._denom;
00102 
00103     cancel();
00104 
00105     return *this;
00106 }
00107 
00108 Rational &Rational::operator*=(const Rational &right) {
00109     // Cross-cancel to avoid unnecessary overflow;
00110     // the result then is automatically normalized
00111     const int gcd1 = gcd(_num, right._denom);
00112     const int gcd2 = gcd(right._num, _denom);
00113 
00114     _num   = (_num    / gcd1) * (right._num    / gcd2);
00115     _denom = (_denom  / gcd2) * (right._denom  / gcd1);
00116 
00117     return *this;
00118 }
00119 
00120 Rational &Rational::operator/=(const Rational &right) {
00121     return *this *= right.getInverse();
00122 }
00123 
00124 Rational &Rational::operator+=(int right) {
00125     return *this += Rational(right);
00126 }
00127 
00128 Rational &Rational::operator-=(int right) {
00129     return *this -= Rational(right);
00130 }
00131 
00132 Rational &Rational::operator*=(int right) {
00133     return *this *= Rational(right);
00134 }
00135 
00136 Rational &Rational::operator/=(int right) {
00137     return *this /= Rational(right);
00138 }
00139 
00140 const Rational Rational::operator-() const {
00141     return Rational(-_num, _denom);
00142 }
00143 
00144 const Rational Rational::operator+(const Rational &right) const {
00145     Rational tmp = *this;
00146     tmp += right;
00147     return tmp;
00148 }
00149 
00150 const Rational Rational::operator-(const Rational &right) const {
00151     Rational tmp = *this;
00152     tmp -= right;
00153     return tmp;
00154 }
00155 
00156 const Rational Rational::operator*(const Rational &right) const {
00157     Rational tmp = *this;
00158     tmp *= right;
00159     return tmp;
00160 }
00161 
00162 const Rational Rational::operator/(const Rational &right) const {
00163     Rational tmp = *this;
00164     tmp /= right;
00165     return tmp;
00166 }
00167 
00168 const Rational Rational::operator+(int right) const {
00169     Rational tmp = *this;
00170     tmp += right;
00171     return tmp;
00172 }
00173 
00174 const Rational Rational::operator-(int right) const {
00175     Rational tmp = *this;
00176     tmp -= right;
00177     return tmp;
00178 }
00179 
00180 const Rational Rational::operator*(int right) const {
00181     Rational tmp = *this;
00182     tmp *= right;
00183     return tmp;
00184 }
00185 
00186 const Rational Rational::operator/(int right) const {
00187     Rational tmp = *this;
00188     tmp /= right;
00189     return tmp;
00190 }
00191 
00192 bool Rational::operator==(const Rational &right) const {
00193     return (_num == right._num) && (_denom == right._denom);
00194 }
00195 
00196 bool Rational::operator!=(const Rational &right) const {
00197     return (_num != right._num) || (_denom != right._denom);
00198 }
00199 
00200 bool Rational::operator>(const Rational &right) const {
00201     return (_num * right._denom) > (right._num * _denom);
00202 }
00203 
00204 bool Rational::operator<(const Rational &right) const {
00205     return (_num * right._denom) < (right._num * _denom);
00206 }
00207 
00208 bool Rational::operator>=(const Rational &right) const {
00209     return (_num * right._denom) >= (right._num * _denom);
00210 }
00211 
00212 bool Rational::operator<=(const Rational &right) const {
00213     return (_num * right._denom) <= (right._num * _denom);
00214 }
00215 
00216 bool Rational::operator==(int right) const {
00217     return (_denom == 1) && (_num == right);
00218 }
00219 
00220 bool Rational::operator!=(int right) const {
00221     return (_denom != 1) || (_num != right);
00222 }
00223 
00224 bool Rational::operator>(int right) const {
00225     return *this > Rational(right, 1);
00226 }
00227 
00228 bool Rational::operator<(int right) const {
00229     return *this < Rational(right, 1);
00230 }
00231 
00232 bool Rational::operator>=(int right) const {
00233     return *this >= Rational(right, 1);
00234 }
00235 
00236 bool Rational::operator<=(int right) const {
00237     return *this <= Rational(right, 1);
00238 }
00239 
00240 void Rational::invert() {
00241     assert(_num != 0);
00242 
00243     SWAP(_num, _denom);
00244 
00245     if (_denom < 0) {
00246         _denom = -_denom;
00247         _num = -_num;
00248     }
00249 }
00250 
00251 Rational Rational::getInverse() const {
00252     Rational inverse = *this;
00253 
00254     inverse.invert();
00255 
00256     return inverse;
00257 }
00258 
00259 int Rational::toInt() const {
00260     return _num / _denom;
00261 }
00262 
00263 double Rational::toDouble() const {
00264     return ((double)_num) / ((double)_denom);
00265 }
00266 
00267 frac_t Rational::toFrac() const {
00268     return (_num * FRAC_ONE) / _denom;
00269 }
00270 
00271 const Rational operator+(int left, const Rational &right) {
00272     Rational tmp(left);
00273     tmp += right;
00274     return tmp;
00275 }
00276 
00277 const Rational operator-(int left, const Rational &right) {
00278     Rational tmp(left);
00279     tmp -= right;
00280     return tmp;
00281 }
00282 
00283 const Rational operator*(int left, const Rational &right) {
00284     Rational tmp(left);
00285     tmp *= right;
00286     return tmp;
00287 }
00288 
00289 const Rational operator/(int left, const Rational &right) {
00290     Rational tmp(left);
00291     tmp /= right;
00292     return tmp;
00293 }
00294 
00295 void Rational::debugPrint(int debuglevel, const char *caption) const {
00296     debug(debuglevel, "%s %d/%d", caption, _num, _denom);
00297 }
00298 
00299 bool operator==(int left, const Rational &right) {
00300     return right == left;
00301 }
00302 
00303 bool operator!=(int left, const Rational &right) {
00304     return right != left;
00305 }
00306 
00307 bool operator>(int left, const Rational &right) {
00308     return right < left;
00309 }
00310 
00311 bool operator<(int left, const Rational &right) {
00312     return right > left;
00313 }
00314 
00315 bool operator>=(int left, const Rational &right) {
00316     return right <= left;
00317 }
00318 
00319 bool operator<=(int left, const Rational &right) {
00320     return right >= left;
00321 }
00322 
00323 } // End of namespace Common


Generated on Sat May 18 2019 05:01:16 for ResidualVM by doxygen 1.7.1
curved edge   curved edge