BWAPI
|
00001 /**************************************************************************** 00002 * Core Library Version 1.7, August 2004 00003 * Copyright (c) 1995-2004 Exact Computation Project 00004 * All rights reserved. 00005 * 00006 * This file is part of CORE (http://cs.nyu.edu/exact/core/); you may 00007 * redistribute it under the terms of the Q Public License version 1.0. 00008 * See the file LICENSE.QPL distributed with CORE. 00009 * 00010 * Licensees holding a valid commercial license may use this file in 00011 * accordance with the commercial license agreement provided with the 00012 * software. 00013 * 00014 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00015 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00016 * 00017 * 00018 * File: BigRat.h 00019 * Synopsis: 00020 * a wrapper class for mpq from GMP 00021 * 00022 * Written by 00023 * Chee Yap <yap@cs.nyu.edu> 00024 * Chen Li <chenli@cs.nyu.edu> 00025 * Zilin Du <zilin@cs.nyu.edu> 00026 * 00027 * WWW URL: http://cs.nyu.edu/exact/ 00028 * Email: exact@cs.nyu.edu 00029 * 00030 * $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Core/include/CGAL/CORE/BigRat.h $ 00031 * $Id: BigRat.h 37435 2007-03-23 23:34:14Z spion $ 00032 ***************************************************************************/ 00033 00034 #ifndef _CORE_BIGRAT_H_ 00035 #define _CORE_BIGRAT_H_ 00036 00037 #include <CGAL/CORE/BigInt.h> 00038 00039 CORE_BEGIN_NAMESPACE 00040 00041 class BigRatRep : public RCRepImpl<BigRatRep> { 00042 public: 00043 BigRatRep() { 00044 mpq_init(mp); 00045 } 00046 // Note : should the copy-ctor be alloed at all ? [Sylvain Pion] 00047 BigRatRep(const BigRatRep& z) : RCRepImpl<BigRatRep>() { 00048 mpq_init(mp); 00049 mpq_set(mp, z.mp); 00050 } 00051 BigRatRep(signed char c) { 00052 mpq_init(mp); 00053 mpq_set_si(mp, c, 1); 00054 } 00055 BigRatRep(unsigned char c) { 00056 mpq_init(mp); 00057 mpq_set_ui(mp, c, 1); 00058 } 00059 BigRatRep(signed int i) { 00060 mpq_init(mp); 00061 mpq_set_si(mp, i, 1); 00062 } 00063 BigRatRep(unsigned int i) { 00064 mpq_init(mp); 00065 mpq_set_ui(mp, i, 1); 00066 } 00067 BigRatRep(signed short int s) { 00068 mpq_init(mp); 00069 mpq_set_si(mp, s, 1); 00070 } 00071 BigRatRep(unsigned short int s) { 00072 mpq_init(mp); 00073 mpq_set_ui(mp, s, 1); 00074 } 00075 BigRatRep(signed long int l) { 00076 mpq_init(mp); 00077 mpq_set_si(mp, l, 1); 00078 } 00079 BigRatRep(unsigned long int l) { 00080 mpq_init(mp); 00081 mpq_set_ui(mp, l, 1); 00082 } 00083 BigRatRep(float f) { 00084 mpq_init(mp); 00085 mpq_set_d(mp, f); 00086 } 00087 BigRatRep(double d) { 00088 mpq_init(mp); 00089 mpq_set_d(mp, d); 00090 } 00091 BigRatRep(const char* s) { 00092 mpq_init(mp); 00093 mpq_set_str(mp, s, 0); 00094 } 00095 BigRatRep(const std::string& s) { 00096 mpq_init(mp); 00097 mpq_set_str(mp, s.c_str(), 0); 00098 } 00099 explicit BigRatRep(mpq_srcptr q) { 00100 mpq_init(mp); 00101 mpq_set(mp, q); 00102 } 00103 BigRatRep(mpz_srcptr z) { 00104 mpq_init(mp); 00105 mpq_set_z(mp, z); 00106 } 00107 BigRatRep(mpz_srcptr n, mpz_srcptr d) { 00108 mpq_init(mp); 00109 mpz_set(mpq_numref(mp), n); 00110 mpz_set(mpq_denref(mp), d); 00111 mpq_canonicalize(mp); 00112 } 00113 ~BigRatRep() { 00114 mpq_clear(mp); 00115 } 00116 00117 CORE_MEMORY(BigRatRep) 00118 00119 mpq_srcptr get_mp() const { 00120 return mp; 00121 } 00122 mpq_ptr get_mp() { 00123 return mp; 00124 } 00125 private: 00126 mpq_t mp; 00127 }; //BigRatRep 00128 00129 class BigFloat; 00130 00131 typedef RCImpl<BigRatRep> RCBigRat; 00132 class BigRat : public RCBigRat { 00133 public: 00135 00136 00137 BigRat() : RCBigRat(new BigRatRep()) {} 00139 BigRat(signed char x) : RCBigRat(new BigRatRep(x)) {} 00141 BigRat(unsigned char x) : RCBigRat(new BigRatRep(x)) {} 00143 BigRat(signed short int x) : RCBigRat(new BigRatRep(x)) {} 00145 BigRat(unsigned short int x) : RCBigRat(new BigRatRep(x)) {} 00147 BigRat(signed int x) : RCBigRat(new BigRatRep(x)) {} 00149 BigRat(unsigned int x) : RCBigRat(new BigRatRep(x)) {} 00151 BigRat(signed long int x) : RCBigRat(new BigRatRep(x)) {} 00153 BigRat(unsigned long int x) : RCBigRat(new BigRatRep(x)) {} 00155 BigRat(float x) : RCBigRat(new BigRatRep(x)) {} 00157 BigRat(double x) : RCBigRat(new BigRatRep(x)) {} 00159 BigRat(const char* s) : RCBigRat(new BigRatRep(s)) {} 00161 BigRat(const std::string& s) : RCBigRat(new BigRatRep(s)) {} 00163 explicit BigRat(mpq_srcptr z) : RCBigRat(new BigRatRep(z)) {} 00165 BigRat(const BigInt& z) : RCBigRat(new BigRatRep(z.get_mp())) {} 00167 BigRat(const BigInt& n, const BigInt& d) 00168 : RCBigRat(new BigRatRep(n.get_mp(), d.get_mp())) {} 00170 BigRat(const BigFloat&); 00172 00174 00175 00176 BigRat(const BigRat& rhs) : RCBigRat(rhs) { 00177 rep->incRef(); 00178 } 00180 BigRat& operator=(const BigRat& rhs) { 00181 if (this != &rhs) { 00182 rep->decRef(); 00183 rep = rhs.rep; 00184 rep->incRef(); 00185 } 00186 return *this; 00187 } 00189 ~BigRat() { 00190 rep->decRef(); 00191 } 00193 00195 00196 BigRat& operator +=(const BigRat& rhs) { 00197 makeCopy(); 00198 mpq_add(get_mp(), get_mp(), rhs.get_mp()); 00199 return *this; 00200 } 00201 BigRat& operator -=(const BigRat& rhs) { 00202 makeCopy(); 00203 mpq_sub(get_mp(), get_mp(), rhs.get_mp()); 00204 return *this; 00205 } 00206 BigRat& operator *=(const BigRat& rhs) { 00207 makeCopy(); 00208 mpq_mul(get_mp(), get_mp(), rhs.get_mp()); 00209 return *this; 00210 } 00211 BigRat& operator /=(const BigRat& rhs) { 00212 makeCopy(); 00213 mpq_div(get_mp(), get_mp(), rhs.get_mp()); 00214 return *this; 00215 } 00216 BigRat& operator <<=(unsigned long ul) { 00217 makeCopy(); 00218 mpq_mul_2exp(get_mp(), get_mp(), ul); 00219 return *this; 00220 } 00221 BigRat& operator >>=(unsigned long ul) { 00222 makeCopy(); 00223 mpq_div_2exp(get_mp(), get_mp(), ul); 00224 return *this; 00225 } 00227 00229 00230 00232 BigRat div2() const { 00233 BigRat r; BigRat t(2); // probably not most efficient way 00234 mpq_div(r.get_mp(), get_mp(), t.get_mp()); 00235 return r; 00236 } 00237 BigRat operator+() const { 00238 return BigRat(*this); 00239 } 00240 BigRat operator-() const { 00241 BigRat r; 00242 mpq_neg(r.get_mp(), get_mp()); 00243 return r; 00244 } 00245 BigRat& operator++() { 00246 makeCopy(); 00247 mpz_add(get_num_mp(),get_num_mp(),get_den_mp()); 00248 return *this; 00249 } 00250 BigRat& operator--() { 00251 makeCopy(); 00252 mpz_sub(get_num_mp(),get_num_mp(),get_den_mp()); 00253 return *this; 00254 } 00255 BigRat operator++(int) { 00256 BigRat r(*this); 00257 ++(*this); 00258 return r; 00259 } 00260 BigRat operator--(int) { 00261 BigRat r(*this); 00262 --(*this); 00263 return r; 00264 } 00266 00268 00269 00270 void canonicalize() { 00271 makeCopy(); 00272 mpq_canonicalize(get_mp()); 00273 } 00275 static bool hasExactDivision() { 00276 return true; 00277 } 00278 00280 mpz_srcptr get_num_mp() const { 00281 return mpq_numref(get_mp()); 00282 } 00284 mpz_ptr get_num_mp() { 00285 return mpq_numref(get_mp()); 00286 } 00288 mpz_srcptr get_den_mp() const { 00289 return mpq_denref(get_mp()); 00290 } 00292 mpz_ptr get_den_mp() { 00293 return mpq_denref(get_mp()); 00294 } 00295 00297 mpq_srcptr get_mp() const { 00298 return rep->get_mp(); 00299 } 00301 mpq_ptr get_mp() { 00302 return rep->get_mp(); 00303 } 00305 00307 00308 00309 int set_str(const char* s, int base = 0) { 00310 makeCopy(); 00311 return mpq_set_str(get_mp(), s, base); 00312 } 00314 std::string get_str(int base = 10) const { 00315 int n = mpz_sizeinbase(mpq_numref(get_mp()), base) + mpz_sizeinbase(mpq_denref(get_mp()), base)+ 3; 00316 char *buffer = new char[n]; 00317 mpq_get_str(buffer, base, get_mp()); 00318 std::string result(buffer); 00319 delete [] buffer; 00320 return result; 00321 } 00323 00325 00326 00327 int intValue() const { 00328 return static_cast<int>(doubleValue()); 00329 } 00331 long longValue() const { 00332 return static_cast<long>(doubleValue()); 00333 } 00335 double doubleValue() const { 00336 return mpq_get_d(get_mp()); 00337 } 00339 BigInt BigIntValue() const { 00340 BigInt r; 00341 mpz_tdiv_q(r.get_mp(), get_num_mp(), get_den_mp()); 00342 return r; 00343 } 00345 }; //BigRat class 00346 00347 inline BigRat operator+(const BigRat& a, const BigRat& b) { 00348 BigRat r; 00349 mpq_add(r.get_mp(), a.get_mp(), b.get_mp()); 00350 return r; 00351 } 00352 inline BigRat operator-(const BigRat& a, const BigRat& b) { 00353 BigRat r; 00354 mpq_sub(r.get_mp(), a.get_mp(), b.get_mp()); 00355 return r; 00356 } 00357 inline BigRat operator*(const BigRat& a, const BigRat& b) { 00358 BigRat r; 00359 mpq_mul(r.get_mp(), a.get_mp(), b.get_mp()); 00360 return r; 00361 } 00362 inline BigRat operator/(const BigRat& a, const BigRat& b) { 00363 BigRat r; 00364 mpq_div(r.get_mp(), a.get_mp(), b.get_mp()); 00365 return r; 00366 } 00367 // Chee (3/19/2004): 00368 // The following definitions of div_exact(x,y) and gcd(x,y) 00369 // ensures that in Polynomial<NT> 00371 inline BigRat div_exact(const BigRat& x, const BigRat& y) { 00372 BigRat z; 00373 mpq_div(z.get_mp(), x.get_mp(), y.get_mp()); 00374 return z; 00375 } 00377 inline BigInt numerator(const BigRat& a) { 00378 return BigInt(a.get_num_mp()); 00379 } 00381 inline BigInt denominator(const BigRat& a) { 00382 return BigInt(a.get_den_mp()); 00383 } 00384 00385 inline BigRat gcd(const BigRat& x, const BigRat& y) { 00386 // return BigRat(1); // Remark: we may want replace this by 00387 // the definition of gcd of a quotient field 00388 // of a UFD [Yap's book, Chap.3] 00389 //Here is one possible definition: gcd of x and y is just the 00390 //gcd of the numerators of x and y divided by the gcd of the 00391 //denominators of x and y. 00392 BigInt n = gcd(numerator(x), numerator(y)); 00393 BigInt d = gcd(denominator(x), denominator(y)); 00394 return BigRat(n,d); 00395 00396 } 00397 // Chee: 8/8/2004: need isDivisible to compile Polynomial<BigRat> 00398 // A trivial implementation is to return true always. But this 00399 // caused tPolyRat to fail. 00400 // So we follow the definition of 00401 // Expr::isDivisible(e1, e2) which checks if e1/e2 is an integer. 00402 inline bool isInteger(const BigRat& x) { 00403 return BigInt(x.get_den_mp()) == 1; 00404 } 00405 inline bool isDivisible(const BigRat& x, const BigRat& y) { 00406 BigRat r; 00407 mpq_div(r.get_mp(), x.get_mp(), y.get_mp()); 00408 return isInteger(r); 00409 } 00410 inline BigRat operator<<(const BigRat& a, unsigned long ul) { 00411 BigRat r; 00412 mpq_mul_2exp(r.get_mp(), a.get_mp(), ul); 00413 return r; 00414 } 00415 inline BigRat operator>>(const BigRat& a, unsigned long ul) { 00416 BigRat r; 00417 mpq_div_2exp(r.get_mp(), a.get_mp(), ul); 00418 return r; 00419 } 00420 00421 inline int cmp(const BigRat& x, const BigRat& y) { 00422 return mpq_cmp(x.get_mp(), y.get_mp()); 00423 } 00424 inline bool operator==(const BigRat& a, const BigRat& b) { 00425 return cmp(a, b) == 0; 00426 } 00427 inline bool operator!=(const BigRat& a, const BigRat& b) { 00428 return cmp(a, b) != 0; 00429 } 00430 inline bool operator>=(const BigRat& a, const BigRat& b) { 00431 return cmp(a, b) >= 0; 00432 } 00433 inline bool operator>(const BigRat& a, const BigRat& b) { 00434 return cmp(a, b) > 0; 00435 } 00436 inline bool operator<=(const BigRat& a, const BigRat& b) { 00437 return cmp(a, b) <= 0; 00438 } 00439 inline bool operator<(const BigRat& a, const BigRat& b) { 00440 return cmp(a, b) < 0; 00441 } 00442 00443 inline std::ostream& operator<<(std::ostream& o, const BigRat& x) { 00444 //return CORE::operator<<(o, x.get_mp()); 00445 return CORE::io_write(o, x.get_mp()); 00446 } 00447 inline std::istream& operator>>(std::istream& i, BigRat& x) { 00448 x.makeCopy(); 00449 //return CORE::operator>>(i, x.get_mp()); 00450 return CORE::io_read(i, x.get_mp()); 00451 } 00452 00454 inline int sign(const BigRat& a) { 00455 return mpq_sgn(a.get_mp()); 00456 } 00458 inline BigRat abs(const BigRat& a) { 00459 BigRat r; 00460 mpq_abs(r.get_mp(), a.get_mp()); 00461 return r; 00462 } 00464 inline BigRat neg(const BigRat& a) { 00465 BigRat r; 00466 mpq_neg(r.get_mp(), a.get_mp()); 00467 return r; 00468 } 00470 inline BigRat div2(const BigRat& a) { 00471 BigRat r(a); 00472 return r.div2(); 00473 } 00475 inline long longValue(const BigRat& a) { 00476 return a.longValue(); 00477 } 00479 inline double doubleValue(const BigRat& a) { 00480 return a.doubleValue(); 00481 } 00483 inline BigInt BigIntValue(const BigRat& a) { 00484 return a.BigIntValue(); 00485 } 00486 00487 CORE_END_NAMESPACE 00488 #endif // _CORE_BIGRAT_H_ 00489