Ticket #9141: 01-rational.patch
File 01-rational.patch, 14.2 KB (added by , 14 years ago) |
---|
-
common/algorithm.h
commit 9da1967937e6fd7424f857165b2a2965ec2059eb Author: Sven Hesse <drmccoy@users.sourceforge.net> Date: Thu May 13 20:20:36 2010 +0200 Adding a simple Rational class that holds fractions diff --git a/common/algorithm.h b/common/algorithm.h index 3a66efe..06f2a27 100644
a b void sort(T first, T last) { 222 222 sort(first, last, Common::Less<typename T::ValueType>()); 223 223 } 224 224 225 /** 226 * Euclid's algorithm to compute the greatest common divisor. 227 */ 228 template<class T> 229 T gcd(T a, T b) { 230 while (a > 0) { 231 T tmp = a; 232 a = b % a; 233 b = tmp; 234 } 235 return b; 236 } 237 225 238 } // End of namespace Common 226 239 #endif 227 240 -
common/module.mk
diff --git a/common/module.mk b/common/module.mk index 2bbb1ed..83d30f0 100644
a b MODULE_OBJS := \ 16 16 md5.o \ 17 17 mutex.o \ 18 18 random.o \ 19 rational.o \ 19 20 str.o \ 20 21 stream.o \ 21 22 system.o \ -
new file common/rational.cpp
diff --git a/common/rational.cpp b/common/rational.cpp new file mode 100644 index 0000000..e27e880
- + 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program 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 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program 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 this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 */ 24 25 #include "common/rational.h" 26 #include "common/util.h" 27 #include "common/algorithm.h" 28 29 namespace Common { 30 31 Rational::Rational() { 32 _num = 1; 33 _denom = 1; 34 } 35 36 Rational::Rational(int num) { 37 _num = num; 38 _denom = 1; 39 } 40 41 Rational::Rational(int num, int denom) { 42 assert(denom != 0); 43 44 _num = num; 45 _denom = denom; 46 47 normalize(); 48 } 49 50 void Rational::cancel() { 51 // Cancel the fraction by dividing both the num and the denom 52 // by their greatest common denom. 53 54 int gcd = Common::gcd(_num, _denom); 55 56 _num /= gcd; 57 _denom /= gcd; 58 } 59 60 void Rational::normalize() { 61 // Is the fraction negative? 62 bool negative = !((!(_num < 0)) == (!(_denom < 0))); 63 64 // Make both integers positive 65 _num = ABS(_num); 66 _denom = ABS(_denom); 67 68 // Cancel the fraction 69 cancel(); 70 71 // If the fraction is supposed to be negative, make the num negative 72 if (negative) 73 _num = -_num; 74 } 75 76 Rational &Rational::operator=(const Rational &right) { 77 _num = right._num; 78 _denom = right._denom; 79 80 return *this; 81 } 82 83 Rational &Rational::operator=(int right) { 84 _num = right; 85 _denom = 1; 86 87 return *this; 88 } 89 90 Rational &Rational::operator+=(const Rational &right) { 91 _num = _num * right._denom + right._num * _denom; 92 _denom = _denom * right._denom; 93 94 normalize(); 95 96 return *this; 97 } 98 99 Rational &Rational::operator-=(const Rational &right) { 100 _num = _num * right._denom - right._num * _denom; 101 _denom = _denom * right._denom; 102 103 normalize(); 104 105 return *this; 106 } 107 108 Rational &Rational::operator*=(const Rational &right) { 109 // Try to cross-cancel first, to avoid unnecessary overflow 110 int gcd1 = Common::gcd(_num, right._denom); 111 int gcd2 = Common::gcd(right._num, _denom); 112 113 _num = (_num / gcd1) * (right._num / gcd2); 114 _denom = (_denom / gcd2) * (right._denom / gcd1); 115 116 normalize(); 117 118 return *this; 119 } 120 121 Rational &Rational::operator/=(const Rational &right) { 122 return *this *= Rational(right._denom, right._num); 123 } 124 125 Rational &Rational::operator+=(int right) { 126 return *this += Rational(right); 127 } 128 129 Rational &Rational::operator-=(int right) { 130 return *this -= Rational(right); 131 } 132 133 Rational &Rational::operator*=(int right) { 134 return *this *= Rational(right); 135 } 136 137 Rational &Rational::operator/=(int right) { 138 return *this /= Rational(right); 139 } 140 141 const Rational Rational::operator-() const { 142 return Rational(-_num, _denom); 143 } 144 145 const Rational Rational::operator+(const Rational &right) const { 146 Rational tmp = *this; 147 148 tmp += right; 149 150 return tmp; 151 } 152 153 const Rational Rational::operator-(const Rational &right) const { 154 Rational tmp = *this; 155 156 tmp -= right; 157 158 return tmp; 159 } 160 161 const Rational Rational::operator*(const Rational &right) const { 162 Rational tmp = *this; 163 164 tmp *= right; 165 166 return tmp; 167 } 168 169 const Rational Rational::operator/(const Rational &right) const { 170 Rational tmp = *this; 171 172 tmp /= right; 173 174 return tmp; 175 } 176 177 const Rational Rational::operator+(int right) const { 178 Rational tmp = *this; 179 180 tmp += right; 181 182 return tmp; 183 } 184 185 const Rational Rational::operator-(int right) const { 186 Rational tmp = *this; 187 188 tmp -= right; 189 190 return tmp; 191 } 192 193 const Rational Rational::operator*(int right) const { 194 Rational tmp = *this; 195 196 tmp *= right; 197 198 return tmp; 199 } 200 201 const Rational Rational::operator/(int right) const { 202 Rational tmp = *this; 203 204 tmp /= right; 205 206 return tmp; 207 } 208 209 bool Rational::operator==(const Rational &right) const { 210 return (_num == right._num) && (_denom == right._denom); 211 } 212 213 bool Rational::operator!=(const Rational &right) const { 214 return (_num != right._num) || (_denom != right._denom); 215 } 216 217 bool Rational::operator>(const Rational &right) const { 218 return (_num * right._denom) > (right._num * _denom); 219 } 220 221 bool Rational::operator<(const Rational &right) const { 222 return (_num * right._denom) < (right._num * _denom); 223 } 224 225 bool Rational::operator>=(const Rational &right) const { 226 return (_num * right._denom) >= (right._num * _denom); 227 } 228 229 bool Rational::operator<=(const Rational &right) const { 230 return (_num * right._denom) <= (right._num * _denom); 231 } 232 233 bool Rational::operator==(int right) const { 234 return (_denom == 1) && (_num == right); 235 } 236 237 bool Rational::operator!=(int right) const { 238 return (_denom == 1) && (_num != right); 239 } 240 241 bool Rational::operator>(int right) const { 242 return *this > Rational(right, 1); 243 } 244 245 bool Rational::operator<(int right) const { 246 return *this < Rational(right, 1); 247 } 248 249 bool Rational::operator>=(int right) const { 250 return *this >= Rational(right, 1); 251 } 252 253 bool Rational::operator<=(int right) const { 254 return *this <= Rational(right, 1); 255 } 256 257 void Rational::invert() { 258 assert(_num != 0); 259 260 SWAP(_num, _denom); 261 262 normalize(); 263 } 264 265 Rational Rational::getInverse() const { 266 Rational inverse = *this; 267 268 inverse.invert(); 269 270 return inverse; 271 } 272 273 int Rational::toInt() const { 274 assert(_denom != 0); 275 276 return _num / _denom; 277 } 278 279 double Rational::toDouble() const { 280 assert(_denom != 0); 281 282 return ((double) _num) / ((double) _denom); 283 } 284 285 frac_t Rational::toFrac() const { 286 return (_num * FRAC_ONE) / _denom; 287 } 288 289 Rational::operator int() const { 290 return toInt(); 291 } 292 293 Rational::operator double() const { 294 return toDouble(); 295 } 296 297 const Rational operator+(int left, const Rational &right) { 298 Rational tmp = right; 299 300 tmp += left; 301 302 return tmp; 303 } 304 305 const Rational operator-(int left, const Rational &right) { 306 Rational tmp = right; 307 308 tmp -= left; 309 310 return tmp; 311 } 312 313 const Rational operator*(int left, const Rational &right) { 314 Rational tmp = right; 315 316 tmp *= left; 317 318 return tmp; 319 } 320 321 const Rational operator/(int left, const Rational &right) { 322 Rational tmp = right; 323 324 tmp /= left; 325 326 return tmp; 327 } 328 329 bool operator==(int left, const Rational &right) { 330 return right == left; 331 } 332 333 bool operator!=(int left, const Rational &right) { 334 return right != left; 335 } 336 337 bool operator>(int left, const Rational &right) { 338 return right < left; 339 } 340 341 bool operator<(int left, const Rational &right) { 342 return right > left; 343 } 344 345 bool operator>=(int left, const Rational &right) { 346 return right <= left; 347 } 348 349 bool operator<=(int left, const Rational &right) { 350 return right >= left; 351 } 352 353 } // End of namespace Common -
new file common/rational.h
diff --git a/common/rational.h b/common/rational.h new file mode 100644 index 0000000..1ad33de
- + 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program 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 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program 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 this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 */ 24 25 #ifndef COMMON_RATIONAL_H 26 #define COMMON_RATIONAL_H 27 28 #include "common/scummsys.h" 29 #include "common/frac.h" 30 31 namespace Common { 32 33 /** A simple rational class that holds fractions. */ 34 class Rational { 35 public: 36 Rational(); 37 Rational(int num); 38 Rational(int num, int denom); 39 40 Rational &operator=(const Rational &right); 41 Rational &operator=(int right); 42 43 Rational &operator+=(const Rational &right); 44 Rational &operator-=(const Rational &right); 45 Rational &operator*=(const Rational &right); 46 Rational &operator/=(const Rational &right); 47 48 Rational &operator+=(int right); 49 Rational &operator-=(int right); 50 Rational &operator*=(int right); 51 Rational &operator/=(int right); 52 53 const Rational operator-() const; 54 55 const Rational operator+(const Rational &right) const; 56 const Rational operator-(const Rational &right) const; 57 const Rational operator*(const Rational &right) const; 58 const Rational operator/(const Rational &right) const; 59 60 const Rational operator+(int right) const; 61 const Rational operator-(int right) const; 62 const Rational operator*(int right) const; 63 const Rational operator/(int right) const; 64 65 bool operator==(const Rational &right) const; 66 bool operator!=(const Rational &right) const; 67 bool operator>(const Rational &right) const; 68 bool operator<(const Rational &right) const; 69 bool operator>=(const Rational &right) const; 70 bool operator<=(const Rational &right) const; 71 72 bool operator==(int right) const; 73 bool operator!=(int right) const; 74 bool operator>(int right) const; 75 bool operator<(int right) const; 76 bool operator>=(int right) const; 77 bool operator<=(int right) const; 78 79 operator int() const; 80 operator double() const; 81 82 void invert(); 83 Rational getInverse() const; 84 85 int toInt() const; 86 double toDouble() const; 87 frac_t toFrac() const; 88 89 private: 90 int _num; 91 int _denom; 92 93 void cancel(); 94 void normalize(); 95 }; 96 97 const Rational operator+(int left, const Rational &right); 98 const Rational operator-(int left, const Rational &right); 99 const Rational operator*(int left, const Rational &right); 100 const Rational operator/(int left, const Rational &right); 101 102 bool operator==(int left, const Rational &right); 103 bool operator!=(int left, const Rational &right); 104 bool operator>(int left, const Rational &right); 105 bool operator<(int left, const Rational &right); 106 bool operator>=(int left, const Rational &right); 107 bool operator<=(int left, const Rational &right); 108 109 } // End of namespace Common 110 111 #endif -
sound/timestamp.cpp
diff --git a/sound/timestamp.cpp b/sound/timestamp.cpp index f705ff4..1eb5483 100644
a b 24 24 */ 25 25 26 26 #include "sound/timestamp.h" 27 #include "common/algorithm.h" 27 28 28 29 namespace Audio { 29 30 30 static uint gcd(uint a, uint b) {31 while (a > 0) {32 int tmp = a;33 a = b % a;34 b = tmp;35 }36 return b;37 }38 39 31 Timestamp::Timestamp(uint ms, uint fr) { 40 32 assert(fr > 0); 41 33 42 34 _secs = ms / 1000; 43 _framerateFactor = 1000 / gcd(1000, fr);35 _framerateFactor = 1000 / Common::gcd<uint>(1000, fr); 44 36 _framerate = fr * _framerateFactor; 45 37 46 38 // Note that _framerate is always divisible by 1000. … … Timestamp::Timestamp(uint s, uint frames, uint fr) { 51 43 assert(fr > 0); 52 44 53 45 _secs = s; 54 _framerateFactor = 1000 / gcd(1000, fr);46 _framerateFactor = 1000 / Common::gcd<uint>(1000, fr); 55 47 _framerate = fr * _framerateFactor; 56 48 _numFrames = frames * _framerateFactor; 57 49 … … Timestamp Timestamp::convertToFramerate(uint newFramerate) const { 62 54 Timestamp ts(*this); 63 55 64 56 if (ts.framerate() != newFramerate) { 65 ts._framerateFactor = 1000 / gcd(1000, newFramerate);57 ts._framerateFactor = 1000 / Common::gcd<uint>(1000, newFramerate); 66 58 ts._framerate = newFramerate * ts._framerateFactor; 67 59 68 const uint g = gcd(_framerate, ts._framerate);60 const uint g = Common::gcd(_framerate, ts._framerate); 69 61 const uint p = _framerate / g; 70 62 const uint q = ts._framerate / g; 71 63 … … bool Timestamp::operator>=(const Timestamp &ts) const { 122 114 int Timestamp::cmp(const Timestamp &ts) const { 123 115 int delta = _secs - ts._secs; 124 116 if (!delta) { 125 const uint g = gcd(_framerate, ts._framerate);117 const uint g = Common::gcd(_framerate, ts._framerate); 126 118 const uint p = _framerate / g; 127 119 const uint q = ts._framerate / g; 128 120 … … void Timestamp::addIntern(const Timestamp &ts) { 164 156 // We need to multiply by the quotient of the two framerates. 165 157 // We cancel the GCD in this fraction to reduce the risk of 166 158 // overflows. 167 const uint g = gcd(_framerate, ts._framerate);159 const uint g = Common::gcd(_framerate, ts._framerate); 168 160 const uint p = _framerate / g; 169 161 const uint q = ts._framerate / g; 170 162 … … int Timestamp::frameDiff(const Timestamp &ts) const { 227 219 // We need to multiply by the quotient of the two framerates. 228 220 // We cancel the GCD in this fraction to reduce the risk of 229 221 // overflows. 230 const uint g = gcd(_framerate, ts._framerate);222 const uint g = Common::gcd(_framerate, ts._framerate); 231 223 const uint p = _framerate / g; 232 224 const uint q = ts._framerate / g; 233 225