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: BigInt.h 00019 * Synopsis: 00020 * a wrapper class for mpz 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/BigInt.h $ 00031 * $Id: BigInt.h 37435 2007-03-23 23:34:14Z spion $ 00032 ***************************************************************************/ 00033 #ifndef _CORE_BIGINT_H_ 00034 #define _CORE_BIGINT_H_ 00035 00036 #include <CGAL/CORE/Gmp.h> 00037 #include <CGAL/CORE/RefCount.h> 00038 #include <CGAL/CORE/MemoryPool.h> 00039 #include <string> 00040 00041 CORE_BEGIN_NAMESPACE 00042 00043 00044 class BigIntRep : public RCRepImpl<BigIntRep> { 00045 public: 00046 BigIntRep() { 00047 mpz_init(mp); 00048 } 00049 // Note : should the copy-ctor be alloed at all ? [Sylvain Pion] 00050 BigIntRep(const BigIntRep& z) : RCRepImpl<BigIntRep>() { 00051 mpz_init_set(mp, z.mp); 00052 } 00053 BigIntRep(signed char c) { 00054 mpz_init_set_si(mp, c); 00055 } 00056 BigIntRep(unsigned char c) { 00057 mpz_init_set_ui(mp, c); 00058 } 00059 BigIntRep(signed int i) { 00060 mpz_init_set_si(mp, i); 00061 } 00062 BigIntRep(unsigned int i) { 00063 mpz_init_set_ui(mp, i); 00064 } 00065 BigIntRep(signed short int s) { 00066 mpz_init_set_si(mp, s); 00067 } 00068 BigIntRep(unsigned short int s) { 00069 mpz_init_set_ui(mp, s); 00070 } 00071 BigIntRep(signed long int l) { 00072 mpz_init_set_si(mp, l); 00073 } 00074 BigIntRep(unsigned long int l) { 00075 mpz_init_set_ui(mp, l); 00076 } 00077 BigIntRep(float f) { 00078 mpz_init_set_d(mp, f); 00079 } 00080 BigIntRep(double d) { 00081 mpz_init_set_d(mp, d); 00082 } 00083 BigIntRep(const char* s, int base=0) { 00084 mpz_init_set_str(mp, s, base); 00085 } 00086 BigIntRep(const std::string& s, int base=0) { 00087 mpz_init_set_str(mp, s.c_str(), base); 00088 } 00089 explicit BigIntRep(mpz_srcptr z) { 00090 mpz_init_set(mp, z); 00091 } 00092 ~BigIntRep() { 00093 mpz_clear(mp); 00094 } 00095 00096 CORE_MEMORY(BigIntRep) 00097 00098 mpz_srcptr get_mp() const { 00099 return mp; 00100 } 00101 mpz_ptr get_mp() { 00102 return mp; 00103 } 00104 private: 00105 mpz_t mp; 00106 }; 00107 00108 typedef RCImpl<BigIntRep> RCBigInt; 00109 class BigInt : public RCBigInt { 00110 public: 00112 00113 00114 BigInt() : RCBigInt(new BigIntRep()) {} 00116 BigInt(signed char x) : RCBigInt(new BigIntRep(x)) {} 00118 BigInt(unsigned char x) : RCBigInt(new BigIntRep(x)) {} 00120 BigInt(signed short int x) : RCBigInt(new BigIntRep(x)) {} 00122 BigInt(unsigned short int x) : RCBigInt(new BigIntRep(x)) {} 00124 BigInt(signed int x) : RCBigInt(new BigIntRep(x)) {} 00126 BigInt(unsigned int x) : RCBigInt(new BigIntRep(x)) {} 00128 BigInt(signed long int x) : RCBigInt(new BigIntRep(x)) {} 00130 BigInt(unsigned long int x) : RCBigInt(new BigIntRep(x)) {} 00132 BigInt(float x) : RCBigInt(new BigIntRep(x)) {} 00134 BigInt(double x) : RCBigInt(new BigIntRep(x)) {} 00136 BigInt(const char* s, int base=0) : RCBigInt(new BigIntRep(s, base)) {} 00138 BigInt(const std::string& s, int base=0) : RCBigInt(new BigIntRep(s, base)) {} 00140 explicit BigInt(mpz_srcptr z) : RCBigInt(new BigIntRep(z)) {} 00142 00144 00145 00146 BigInt(const BigInt& rhs) : RCBigInt(rhs) { 00147 rep->incRef(); 00148 } 00150 BigInt& operator=(const BigInt& rhs) { 00151 if (this != &rhs) { 00152 rep->decRef(); 00153 rep = rhs.rep; 00154 rep->incRef(); 00155 } 00156 return *this; 00157 } 00159 ~BigInt() { 00160 rep->decRef(); 00161 } 00163 00165 00166 BigInt& operator +=(const BigInt& rhs) { 00167 makeCopy(); 00168 mpz_add(get_mp(), get_mp(), rhs.get_mp()); 00169 return *this; 00170 } 00171 BigInt& operator -=(const BigInt& rhs) { 00172 makeCopy(); 00173 mpz_sub(get_mp(), get_mp(), rhs.get_mp()); 00174 return *this; 00175 } 00176 BigInt& operator *=(const BigInt& rhs) { 00177 makeCopy(); 00178 mpz_mul(get_mp(), get_mp(), rhs.get_mp()); 00179 return *this; 00180 } 00181 BigInt& operator /=(const BigInt& rhs) { 00182 makeCopy(); 00183 mpz_tdiv_q(get_mp(), get_mp(), rhs.get_mp()); 00184 return *this; 00185 } 00186 BigInt& operator %=(const BigInt& rhs) { 00187 makeCopy(); 00188 mpz_tdiv_r(get_mp(), get_mp(), rhs.get_mp()); 00189 return *this; 00190 } 00191 BigInt& operator &=(const BigInt& rhs) { 00192 makeCopy(); 00193 mpz_and(get_mp(), get_mp(), rhs.get_mp()); 00194 return *this; 00195 } 00196 BigInt& operator |=(const BigInt& rhs) { 00197 makeCopy(); 00198 mpz_ior(get_mp(), get_mp(), rhs.get_mp()); 00199 return *this; 00200 } 00201 BigInt& operator ^=(const BigInt& rhs) { 00202 makeCopy(); 00203 mpz_xor(get_mp(), get_mp(), rhs.get_mp()); 00204 return *this; 00205 } 00206 BigInt& operator <<=(unsigned long ul) { 00207 makeCopy(); 00208 mpz_mul_2exp(get_mp(), get_mp(), ul); 00209 return *this; 00210 } 00211 BigInt& operator >>=(unsigned long ul) { 00212 makeCopy(); 00213 mpz_tdiv_q_2exp(get_mp(), get_mp(), ul); 00214 return *this; 00215 } 00217 00219 00220 BigInt operator+() const { 00221 return BigInt(*this); 00222 } 00223 BigInt operator-() const { 00224 BigInt r; 00225 mpz_neg(r.get_mp(), get_mp()); 00226 return r; 00227 } 00228 BigInt& operator++() { 00229 makeCopy(); 00230 mpz_add_ui(get_mp(), get_mp(), 1); 00231 return *this; 00232 } 00233 BigInt& operator--() { 00234 makeCopy(); 00235 mpz_sub_ui(get_mp(), get_mp(), 1); 00236 return *this; 00237 } 00238 BigInt operator++(int) { 00239 BigInt r(*this); 00240 ++(*this); 00241 return r; 00242 } 00243 BigInt operator--(int) { 00244 BigInt r(*this); 00245 --(*this); 00246 return r; 00247 } 00249 00251 00252 00253 static bool hasExactDivision() { 00254 return false; 00255 } 00257 mpz_srcptr get_mp() const { 00258 return rep->get_mp(); 00259 } 00261 mpz_ptr get_mp() { 00262 return rep->get_mp(); 00263 } 00265 00267 00268 00269 int set_str(const char* s, int base = 0) { 00270 makeCopy(); 00271 return mpz_set_str(get_mp(), s, base); 00272 } 00274 std::string get_str(int base = 10) const { 00275 int n = mpz_sizeinbase (get_mp(), base) + 2; 00276 char *buffer = new char[n]; 00277 mpz_get_str(buffer, base, get_mp()); 00278 std::string result(buffer); 00279 delete [] buffer; 00280 return result; 00281 } 00283 00285 00286 00287 int intValue() const { 00288 return static_cast<int>(mpz_get_si(get_mp())); 00289 } 00291 long longValue() const { 00292 return mpz_get_si(get_mp()); 00293 } 00295 unsigned long ulongValue() const { 00296 return mpz_get_ui(get_mp()); 00297 } 00299 double doubleValue() const { 00300 return mpz_get_d(get_mp()); 00301 } 00303 }; 00304 00305 inline BigInt operator+(const BigInt& a, const BigInt& b) { 00306 BigInt r; 00307 mpz_add(r.get_mp(), a.get_mp(), b.get_mp()); 00308 return r; 00309 } 00310 inline BigInt operator-(const BigInt& a, const BigInt& b) { 00311 BigInt r; 00312 mpz_sub(r.get_mp(), a.get_mp(), b.get_mp()); 00313 return r; 00314 } 00315 inline BigInt operator*(const BigInt& a, const BigInt& b) { 00316 BigInt r; 00317 mpz_mul(r.get_mp(), a.get_mp(), b.get_mp()); 00318 return r; 00319 } 00320 inline BigInt operator/(const BigInt& a, const BigInt& b) { 00321 BigInt r; 00322 mpz_tdiv_q(r.get_mp(), a.get_mp(), b.get_mp()); 00323 return r; 00324 } 00325 inline BigInt operator%(const BigInt& a, const BigInt& b) { 00326 BigInt r; 00327 mpz_tdiv_r(r.get_mp(), a.get_mp(), b.get_mp()); 00328 return r; 00329 } 00330 inline BigInt operator&(const BigInt& a, const BigInt& b) { 00331 BigInt r; 00332 mpz_and(r.get_mp(), a.get_mp(), b.get_mp()); 00333 return r; 00334 } 00335 inline BigInt operator|(const BigInt& a, const BigInt& b) { 00336 BigInt r; 00337 mpz_ior(r.get_mp(), a.get_mp(), b.get_mp()); 00338 return r; 00339 } 00340 inline BigInt operator^(const BigInt& a, const BigInt& b) { 00341 BigInt r; 00342 mpz_xor(r.get_mp(), a.get_mp(), b.get_mp()); 00343 return r; 00344 } 00345 inline BigInt operator<<(const BigInt& a, unsigned long ul) { 00346 BigInt r; 00347 mpz_mul_2exp(r.get_mp(), a.get_mp(), ul); 00348 return r; 00349 } 00350 inline BigInt operator>>(const BigInt& a, unsigned long ul) { 00351 BigInt r; 00352 mpz_tdiv_q_2exp(r.get_mp(), a.get_mp(), ul); 00353 return r; 00354 } 00355 00356 inline int cmp(const BigInt& x, const BigInt& y) { 00357 return mpz_cmp(x.get_mp(), y.get_mp()); 00358 } 00359 inline bool operator==(const BigInt& a, const BigInt& b) { 00360 return cmp(a, b) == 0; 00361 } 00362 inline bool operator!=(const BigInt& a, const BigInt& b) { 00363 return cmp(a, b) != 0; 00364 } 00365 inline bool operator>=(const BigInt& a, const BigInt& b) { 00366 return cmp(a, b) >= 0; 00367 } 00368 inline bool operator>(const BigInt& a, const BigInt& b) { 00369 return cmp(a, b) > 0; 00370 } 00371 inline bool operator<=(const BigInt& a, const BigInt& b) { 00372 return cmp(a, b) <= 0; 00373 } 00374 inline bool operator<(const BigInt& a, const BigInt& b) { 00375 return cmp(a, b) < 0; 00376 } 00377 00378 inline std::ostream& operator<<(std::ostream& o, const BigInt& x) { 00379 //return CORE::operator<<(o, x.get_mp()); 00380 return CORE::io_write(o, x.get_mp()); 00381 } 00382 inline std::istream& operator>>(std::istream& i, BigInt& x) { 00383 x.makeCopy(); 00384 //return CORE::operator>>(i, x.get_mp()); 00385 return CORE::io_read(i, x.get_mp()); 00386 } 00387 00389 inline int sign(const BigInt& a) { 00390 return mpz_sgn(a.get_mp()); 00391 } 00393 inline BigInt abs(const BigInt& a) { 00394 BigInt r; 00395 mpz_abs(r.get_mp(), a.get_mp()); 00396 return r; 00397 } 00399 inline BigInt neg(const BigInt& a) { 00400 BigInt r; 00401 mpz_neg(r.get_mp(), a.get_mp()); 00402 return r; 00403 } 00405 inline void negate(BigInt& a) { 00406 a.makeCopy(); 00407 mpz_neg(a.get_mp(), a.get_mp()); 00408 } 00410 inline int cmpabs(const BigInt& a, const BigInt& b) { 00411 return mpz_cmpabs(a.get_mp(), b.get_mp()); 00412 } 00413 00415 00416 00417 inline long longValue(const BigInt& a) { 00418 return a.longValue(); 00419 } 00421 inline unsigned long ulongValue(const BigInt& a) { 00422 return a.ulongValue(); 00423 } 00425 inline double doubleValue(const BigInt& a) { 00426 return a.doubleValue(); 00427 } 00429 00431 00432 00433 void readFromFile(BigInt& z, std::istream& in, long maxLength = 0); 00435 void writeToFile(const BigInt& z, std::ostream& in, int base=10, int charsPerLine=80); 00437 00439 00440 00441 inline bool isEven(const BigInt& z) { 00442 return mpz_even_p(z.get_mp()); 00443 } 00445 inline bool isOdd(const BigInt& z) { 00446 return mpz_odd_p(z.get_mp()); 00447 } 00448 00450 inline unsigned long getBinExpo(const BigInt& z) { 00451 return mpz_scan1(z.get_mp(), 0); 00452 } 00454 inline void getKaryExpo(const BigInt& z, BigInt& m, int& e, unsigned long k) { 00455 mpz_t f; 00456 mpz_init_set_ui(f, k); 00457 m.makeCopy(); 00458 e = mpz_remove(m.get_mp(), z.get_mp(), f); 00459 mpz_clear(f); 00460 } 00461 00463 inline bool isDivisible(const BigInt& x, const BigInt& y) { 00464 return mpz_divisible_p(x.get_mp(), y.get_mp()) != 0; 00465 } 00466 inline bool isDivisible(int x, int y) { 00467 return x % y == 0; 00468 } 00469 inline bool isDivisible(long x, long y) { 00470 return x % y == 0; 00471 } 00473 inline void divexact(BigInt& z, const BigInt& x, const BigInt& y) { 00474 z.makeCopy(); 00475 mpz_divexact(z.get_mp(), x.get_mp(), y.get_mp()); 00476 } 00477 // Chee (1/12/2004) The definition of div_exact(x,y) next 00478 // ensure that in Polynomials<NT> works with both NT=BigInt and NT=int: 00479 inline BigInt div_exact(const BigInt& x, const BigInt& y) { 00480 BigInt z; // precodition: isDivisible(x,y) 00481 divexact(z, x, y); // z is set to x/y; 00482 return z; 00483 } 00484 inline int div_exact(int x, int y) { 00485 return x/y; // precondition: isDivisible(x,y) 00486 } 00487 inline long div_exact(long x, long y) { 00488 return x/y; // precondition: isDivisible(x,y) 00489 } 00490 00491 00493 inline BigInt gcd(const BigInt& a, const BigInt& b) { 00494 BigInt r; 00495 mpz_gcd(r.get_mp(), a.get_mp(), b.get_mp()); 00496 return r; 00497 } 00499 inline void div_rem(BigInt& q, BigInt& r, const BigInt& a, const BigInt& b) { 00500 q.makeCopy(); 00501 r.makeCopy(); 00502 mpz_tdiv_qr(q.get_mp(), r.get_mp(), a.get_mp(), b.get_mp()); 00503 } 00505 inline void power(BigInt& c, const BigInt& a, unsigned long ul) { 00506 c.makeCopy(); 00507 mpz_pow_ui(c.get_mp(), a.get_mp(), ul); 00508 } 00509 00510 // pow 00511 inline BigInt pow(const BigInt& a, unsigned long ui) { 00512 BigInt r; 00513 power(r, a, ui); 00514 return r; 00515 } 00516 00517 // bit length 00518 inline int bitLength(const BigInt& a) { 00519 return mpz_sizeinbase(a.get_mp(), 2); 00520 } 00522 00525 inline long floorLg(const BigInt& a) { 00526 return (sign(a) == 0) ? (-1) : (bitLength(a)-1); 00527 } 00529 00532 inline long ceilLg(const BigInt& a) { 00533 if (sign(a) == 0) 00534 return -1; 00535 unsigned long len = bitLength(a); 00536 return (mpz_scan1(a.get_mp(), 0) == len-1) ? (len-1) : len; 00537 } 00538 inline long ceilLg(long a) { // need this for Polynomial<long> 00539 return ceilLg(BigInt(a)); 00540 } 00541 inline long ceilLg(int a) { // need this for Polynomial<int> 00542 return ceilLg(BigInt(a)); 00543 } 00544 00545 00546 // return a gmp_randstate_t structure 00547 extern gmp_randstate_t* getRandstate(); 00549 inline void seed(const BigInt& a) { 00550 gmp_randseed(*getRandstate(), a.get_mp()); 00551 } 00553 inline BigInt randomize(const BigInt& a) { 00554 BigInt r; 00555 mpz_urandomm(r.get_mp(), *getRandstate(), a.get_mp()); 00556 return r; 00557 } 00559 00560 CORE_END_NAMESPACE 00561 #endif // _CORE_BIGINT_H_