BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/CORE/BigInt.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines