realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/scalar_integer.hpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 *      This file is part of the source code of ALP software.         *
00003 *      (C) B. Mourrain, GALAAD, INRIA                                *
00004 **********************************************************************
00005 History: 
00006 $Id: scalar_mpz.H,v 1.1.1.1 2006/10/06 08:01:40 trebuche Exp $
00007 **********************************************************************/
00008 #ifndef _scalar_integer_hpp
00009 #define _scalar_integer_hpp
00010 //----------------------------------------------------------------------
00011 #include <iostream>
00012 #include <string>
00013 #include <gmp.h>
00014 #include <realroot/scalar.hpp>
00015 //======================================================================
00016 namespace mmx {
00017 //----------------------------------------------------------------------
00018 typedef MP_INT MPZ;
00019 //----------------------------------------------------------------------
00020 //  template<> inline
00021 //  shared_object<MPZ>::rep::~rep()           
00022 //  {
00023 //    //COUT <<"Delete mpz"<<endl;
00024 //    mpz_clear(&obj);
00025 //  }
00026 //----------------------------------------------------------------------
00027 template<> inline scalar<MPZ>::~scalar ( )      
00028 { 
00029   //COUT <<"Delete mpz"<<endl;
00030   mpz_clear(&rep());
00031 }
00032 //----------------------------------------------------------------------
00033 template<> inline
00034 void scalar<MPZ>::init ( )                   
00035 { 
00036   mpz_init(&rep());
00037 }
00038 //------------------- scalar<T> (...) -------------------------------------
00039 template<> inline
00040 scalar<MPZ>::scalar () //: data()            
00041 {
00042   mpz_init(&rep());
00043 }
00044 //----------------------------------------------------------------------
00045 template<> inline
00046 scalar<MPZ>::scalar (signed long int sl): data()  {mpz_init_set_si(&rep(),sl);}
00047 //----------------------------------------------------------------------
00048 template<> inline
00049 scalar<MPZ>::scalar (unsigned long int ul): data() {mpz_init_set_ui(&rep(),ul);}
00050 //----------------------------------------------------------------------
00051 template<> inline
00052 scalar<MPZ>::scalar (int si): data()               {mpz_init_set_si(&rep(), si);}
00053 //----------------------------------------------------------------------
00054 template<> inline
00055 scalar<MPZ>::scalar (const char *s, unsigned int base): data()
00056 {
00057   if (mpz_init_set_str(&rep(), s, base))
00058     std::cerr << "scalar<MPZ>: The string " << s 
00059               << " is not a valid number in base " << base << std::endl;
00060 }
00061 //----------------------------------------------------------------------
00062 template<> inline
00063 scalar<MPZ>::scalar (const scalar<MPZ> & rhs)
00064 {
00065   //COUT <<"Init mpz"<<endl;
00066   //COUNT<MPZ>('c');
00067   mpz_init_set(&rep(), &rhs.rep());      
00068 }
00069 //{ data=b.data;}
00070 //----------------------------------------------------------------------
00071 template<> inline 
00072 scalar<MPZ>& scalar<MPZ>::operator =  (const scalar<MPZ>& rhs)
00073 {
00074   //COUNT<MPZ>('=');
00075   if (this != &rhs) mpz_set(&rep(), &rhs.rep()); 
00076   return *this;
00077 }
00078 template<> inline 
00079 scalar<MPZ>& scalar<MPZ>::operator =  (unsigned rhs)
00080 {
00081   //COUNT<MPZ>('=');
00082   mpz_set_ui(&rep(), rhs); 
00083   return *this;
00084 }
00085 // == ------------------------------------------------------------------
00086 template<> inline 
00087 bool scalar<MPZ>::operator == (const scalar<MPZ>& rhs) const
00088 {
00089   return mpz_cmp(&rep(), &rhs.rep()) == 0;
00090 }
00091 
00092 template<> inline 
00093 bool scalar<MPZ>::operator == (long sl) const {
00094   return mpz_cmp_si(&rep(), sl) == 0;
00095 }
00096 
00097 template<> inline 
00098 bool scalar<MPZ>::operator == (int si) const {
00099   return mpz_cmp_si(&rep(), (long) si) == 0;
00100 }
00101 
00102 template<> inline 
00103 bool scalar<MPZ>::operator == (unsigned long ul) const
00104 {
00105   return mpz_cmp_ui(&rep(), ul) == 0;
00106 }
00107 
00108 // != ------------------------------------------------------------------
00109 template<> inline 
00110 bool scalar<MPZ>::operator != (const scalar<MPZ>& rhs) const
00111 {
00112   return mpz_cmp(&rep(), &rhs.rep()) != 0;
00113 }
00114 
00115 template<> inline 
00116 bool scalar<MPZ>::operator != (long sl) const {
00117   return mpz_cmp_si(&rep(), sl) != 0;
00118 }
00119 
00120 template<> inline
00121 bool scalar<MPZ>::operator != (int si) const {
00122   return mpz_cmp_si(&rep(), (long) si) != 0;
00123 }
00124 
00125 template<> inline 
00126 bool scalar<MPZ>::operator != (unsigned long ul) const
00127 {
00128   return mpz_cmp_ui(&rep(), ul) != 0;
00129 }
00130 // > -------------------------------------------------------------------
00131 template<> inline 
00132 bool scalar<MPZ>::operator > (const scalar<MPZ>& rhs) const
00133 {
00134   return mpz_cmp(&rep(), &rhs.rep()) > 0;
00135 }
00136 
00137 template<> inline 
00138 bool scalar<MPZ>::operator > (long sl) const {
00139   return mpz_cmp_si(&rep(), sl) > 0;
00140 }
00141 
00142 template<> inline 
00143 bool scalar<MPZ>::operator > (int si) const {
00144   return mpz_cmp_si(&rep(), (long) si) > 0;
00145 }
00146 
00147 template<> inline 
00148 bool scalar<MPZ>::operator > (unsigned long ul) const
00149 {
00150   return mpz_cmp_ui(&rep(), ul) > 0;
00151 }
00152 // <= --------------------------------------------------------------------
00153 template<> inline 
00154 bool scalar<MPZ>::operator >= (const scalar<MPZ>& rhs) const
00155 {
00156   return mpz_cmp(&rep(), &rhs.rep()) >= 0;
00157 }
00158 
00159 template<> inline 
00160 bool scalar<MPZ>::operator >= (long sl) const {
00161   return mpz_cmp_si(&rep(), sl) >= 0;
00162 }
00163 
00164 template<> inline 
00165 bool scalar<MPZ>::operator >= (int si) const
00166 {
00167   return mpz_cmp_si(&rep(), (long) si) >= 0;
00168 }
00169 
00170 template<> inline 
00171 bool scalar<MPZ>::operator >= (unsigned long ul) const
00172 {
00173   return mpz_cmp_ui(&rep(), ul) >= 0;
00174 }
00175 
00176 // < -------------------------------------------------------------------
00177 template<> inline 
00178 bool scalar<MPZ>::operator < (const scalar<MPZ>& rhs) const
00179 {
00180   return mpz_cmp(&rep(), &rhs.rep()) < 0;
00181 }
00182 
00183 template<> inline 
00184 bool scalar<MPZ>::operator < (long sl) const {
00185   return mpz_cmp_si(&rep(), sl) < 0;
00186 }
00187 
00188 template<> inline 
00189 bool scalar<MPZ>::operator < (int si) const
00190 {
00191   return mpz_cmp_si(&rep(), (long) si) < 0;
00192 }
00193 
00194 template<> inline 
00195 bool scalar<MPZ>::operator < (unsigned long ul) const
00196 {
00197   return mpz_cmp_ui(&rep(), ul) < 0;
00198 }
00199 
00200 // <= ------------------------------------------------------------------
00201 
00202 template<> inline 
00203 bool scalar<MPZ>::operator <= (const scalar<MPZ>& rhs) const
00204 {
00205   return mpz_cmp(&rep(), &rhs.rep()) <= 0;
00206 }
00207 
00208 template<> inline 
00209 bool scalar<MPZ>::operator <= (long sl) const {
00210   return mpz_cmp_si(&rep(), sl) <= 0;
00211 }
00212 
00213 template<> inline 
00214 bool scalar<MPZ>::operator <= (int si) const
00215 {
00216   return mpz_cmp_si(&rep(), (long) si) <= 0;
00217 }
00218 
00219 template<> inline 
00220 bool scalar<MPZ>::operator <= (unsigned long ul) const
00221 {
00222   return mpz_cmp_ui(&rep(), ul) <= 0;
00223 }
00224 
00225 // = -------------------------------------------------------------------
00226 template<> inline 
00227 scalar<MPZ>&  scalar<MPZ>::operator =  (unsigned long ul)
00228 {
00229   mpz_set_ui(&rep(), ul); return *this;
00230 }
00231 
00232 template<> inline 
00233 scalar<MPZ>& scalar<MPZ>::operator =  (long sl)
00234 {
00235   mpz_set_si(&rep(), sl);  return *this;
00236 }
00237 
00238 template<> inline 
00239 scalar<MPZ>& scalar<MPZ>::operator = (int ul)
00240 {
00241   mpz_init_set_si(&(this->rep()), ul);  return *this;
00242 }
00243 // += -------------------------------------------------------------------
00244 template<> inline 
00245 scalar<MPZ>& scalar<MPZ>::operator += (const scalar<MPZ>& rhs)
00246 {
00247   mpz_add(&rep(), &rep(), &rhs.rep());  return *this;
00248 }
00249 
00250 template<> inline 
00251 scalar<MPZ>& scalar<MPZ>::operator += (unsigned long ul)
00252 {
00253   mpz_add_ui(&rep(), &rep(), ul); return *this;
00254 }
00255 
00256 template<> inline 
00257 scalar<MPZ>& scalar<MPZ>::operator += (long sl)
00258 {
00259   if (sl >= 0)
00260     mpz_add_ui(&rep(), &rep(), (unsigned long) sl);
00261   else
00262     mpz_sub_ui(&rep(), &rep(), ((unsigned long) -sl));
00263   return *this;
00264 }
00265 
00266 template<> inline 
00267 scalar<MPZ>& scalar<MPZ>::operator += (int ul)
00268 {
00269   *this += scalar<MPZ>(ul);  return *this;
00270 }
00271 
00272 // -= -------------------------------------------------------------------
00273 template<> inline 
00274 scalar<MPZ>& scalar<MPZ>::operator -= (const scalar<MPZ>& rhs)
00275 {
00276   mpz_sub(&rep(), &rep(), &rhs.rep()); return *this;
00277 }
00278 
00279 template<> inline 
00280 scalar<MPZ>& scalar<MPZ>::operator -= (unsigned long ul)
00281 {
00282   mpz_sub_ui(&rep(), &rep(), ul); return *this;
00283 }
00284 
00285 template<> inline 
00286 scalar<MPZ>& scalar<MPZ>::operator -= (long sl)
00287 {
00288   if (sl >= 0)
00289     mpz_sub_ui(&rep(), &rep(), (unsigned long) sl);
00290   else
00291     mpz_add_ui(&rep(), &rep(), (unsigned long) sl);
00292   return *this;
00293 }
00294 
00295 template<> inline 
00296 scalar<MPZ>& scalar<MPZ>::operator -= (int ul)
00297 {
00298   *this -= scalar<MPZ>(ul); return *this;
00299 }
00300 // *= -----------------------------------------------------------------
00301 template<> inline 
00302 scalar<MPZ>& scalar<MPZ>::operator *= (const scalar<MPZ>& rhs)
00303 {
00304   mpz_mul(&rep(), &rep(), &rhs.rep()); return *this;
00305 }
00306 template<> inline 
00307 scalar<MPZ>& scalar<MPZ>::operator *= (unsigned long ul)
00308 {
00309   mpz_mul_ui(&rep(), &rep(), ul); return *this;
00310 }
00311 template<> inline 
00312 scalar<MPZ>& scalar<MPZ>::operator *= (long sl)
00313 {
00314   if (sl >= 0)
00315     mpz_mul_ui(&rep(), &rep(), (unsigned long) sl);
00316   else
00317     {
00318       rep()._mp_size = -rep()._mp_size;
00319       mpz_mul_ui(&rep(), &rep(), ((unsigned long) -sl));
00320     }
00321   return *this; 
00322 }
00323 template<> inline 
00324 scalar<MPZ>& scalar<MPZ>::operator *= (int ul)
00325 {
00326    if (ul >= 0)
00327      mpz_mul_ui(&rep(), &rep(), (unsigned long) ul);
00328    else {
00329      mpz_mul_ui(&rep(), &rep(), (unsigned long) (-ul));
00330      mpz_neg(&rep(), &rep());
00331    }
00332    return *this;
00333 }
00334 // /= ------------------------------------------------------------------
00335 template<> inline 
00336 scalar<MPZ>& scalar<MPZ>::operator /= (const scalar<MPZ>& rhs)
00337 {
00338   mpz_div(&rep(), &rep(), &rhs.rep());
00339   //mpz_divexact(&rep(), &rep(), &rhs.rep()); 
00340   return *this;
00341 }
00342 template<> inline 
00343 scalar<MPZ>& scalar<MPZ>::operator /= (unsigned long ul)
00344 {
00345   mpz_div_ui(&rep(), &rep(), ul); return *this;
00346 }
00347 
00348 template<> inline 
00349 scalar<MPZ>& scalar<MPZ>::operator /= (long sl)
00350 {
00351   if (sl >= 0)
00352     mpz_div_ui(&rep(), &rep(), (unsigned long) sl);
00353   else
00354     {
00355       rep()._mp_size = -rep()._mp_size;
00356       mpz_div_ui(&rep(), &rep(), ((unsigned long) -sl));
00357     }
00358   return *this;
00359 }
00360 
00361 // %= ------------------------------------------------------------------
00362 template<> inline 
00363 scalar<MPZ>& scalar<MPZ>::operator %= (const scalar<MPZ>& rhs)
00364 {
00365   mpz_mod(&rep(), &rep(), &rhs.rep()); return *this;
00366 }
00367 
00368 template<> inline 
00369 scalar<MPZ>& scalar<MPZ>::operator %= (unsigned long ul)
00370 {
00371   mpz_mod_ui(&rep(), &rep(), ul); return *this;
00372 }
00373 
00374 //======================================================================
00375 // ARITHMETIC OPERATORS
00376 //======================================================================
00377 inline
00378 scalar<MPZ> operator +(const scalar<MPZ>& a1, const scalar<MPZ>& a2) 
00379 {
00380   scalar<MPZ> result;
00381   mpz_add(&result.rep(), &a1.rep(), &a2.rep());
00382   return result;
00383 }
00384 //----------------------------------------------------------------------
00385 inline
00386 scalar<MPZ> operator -(const scalar<MPZ>& a1, const scalar<MPZ>& a2) 
00387 {
00388    scalar<MPZ> result;
00389    mpz_sub(&result.rep(), &a1.rep(), &a2.rep());
00390    return result;
00391  }
00392 
00393 inline
00394 scalar<MPZ> operator -(const scalar<MPZ>& a1) 
00395 {
00396   scalar<MPZ> r;  mpz_neg(&r.rep(), &a1.rep()); return r;
00397 }
00398 //----------------------------------------------------------------------
00399 inline
00400 scalar<MPZ> operator *(const scalar<MPZ>& a1, const scalar<MPZ>& a2) 
00401 {
00402   scalar<MPZ> result;
00403   mpz_mul(&result.rep(), &a1.rep(), &a2.rep());
00404   return result;
00405 }
00406 
00407 //--------------------------------------------------------------------
00408 inline 
00409 scalar<MPZ> operator /(const scalar<MPZ>& a1, const scalar<MPZ>& a2) 
00410 {
00411   scalar<MPZ> result;
00412   mpz_div(&result.rep(), &a1.rep(), &a2.rep());
00413   return result;
00414 }
00415 //======================================================================
00417 template<> inline 
00418 void scalar<MPZ>::operator ++ ( )
00419 {
00420   mpz_add_ui(&rep(), &rep(), 1);
00421 }
00422 //----------------------------------------------------------------------
00424 template<> inline 
00425 void scalar<MPZ>::operator -- ( )
00426 {
00427   mpz_sub_ui(&rep(), &rep(), 1);
00428 }
00429 //======================================================================
00430 inline void convert(scalar<MPZ>& n, char *s) 
00431 {
00432   mpz_init_set_str(&n.rep(), s, 10);
00433 }
00434 //======================================================================
00435 // INPUT OUTPUT
00436 //======================================================================
00437 inline
00438 std::ostream& operator << (std::ostream& os, const scalar<MPZ>& b)
00439 {
00440   mpz_out_str(stdout, 10, &b.rep());
00441   return os;
00442 }
00443 //----------------------------------------------------------------------
00444 inline
00445 std::istream& operator >> (std::istream& is, scalar<MPZ>& b)
00446 {
00447   std::string s;is >> s;
00448   mpz_init_set_str(&b.rep(),s.c_str(), 10);
00449   return is;
00450 }
00451 //======================================================================
00452 // SPECIAL FUNCTIONS
00453 //======================================================================
00454 template<> inline void
00455 scalar<MPZ>::Div2Exp (unsigned long exponent_of_2)
00456 {
00457   mpz_div_2exp(&rep(), &rep(), exponent_of_2);
00458 }
00459 
00460 template<> inline 
00461 void scalar<MPZ>::GCD (const scalar<MPZ>& b2)
00462 {
00463     mpz_gcd (&rep(), &rep(), &b2.rep());
00464 }
00465 
00466 
00467 template<> inline void
00468 scalar<MPZ>::Mod2Exp (unsigned long exponent_of_2)
00469 {
00470   mpz_mod_2exp(&rep(), &rep(), exponent_of_2);
00471 }
00472 
00473 template<> inline void
00474 scalar<MPZ>::Mul2Exp (unsigned long exponent_of_2)
00475 {
00476   mpz_mul_2exp(&rep(), &rep(), exponent_of_2);
00477 }
00478 
00479 template<> inline void
00480 scalar<MPZ>::PowMod (const scalar<MPZ>& exp, const scalar<MPZ>& m)
00481 {
00482   mpz_powm(&rep(), &rep(), &exp.rep(), &m.rep());
00483 }
00484 
00485 template<> inline void
00486 scalar<MPZ>::PowMod (unsigned long exp, const scalar<MPZ>& m)
00487 {
00488   mpz_powm_ui(&rep(), &rep(), exp, &m.rep());
00489 }
00490 
00491 template<> inline void
00492 scalar<MPZ>::abs ( )
00493 {
00494   if (rep()._mp_size < 0)
00495     rep()._mp_size = - rep()._mp_size;
00496 }
00497 
00498 template<> inline void
00499 scalar<MPZ>::factorial (unsigned long n)
00500 {
00501   mpz_fac_ui(&rep(), n);
00502 }
00503 
00504 template<> inline 
00505 scalar<MPZ>& scalar<MPZ>::negate ( )
00506 {
00507   rep()._mp_size = - rep()._mp_size; return *this;
00508 }
00509 
00510 template<> inline 
00511 scalar<MPZ>& scalar<MPZ>::pow (unsigned long exp)
00512 {
00513   mpz_pow_ui(&rep(), &rep(), exp); return *this;
00514 }
00515 
00516 template<> inline 
00517 scalar<MPZ>& scalar<MPZ>::pow (unsigned long base, unsigned long exp)
00518 {
00519   mpz_ui_pow_ui(&rep(), base, exp); return *this;
00520 }
00521 
00522 template<> inline void
00523 scalar<MPZ>::quo (const scalar<MPZ>& divisor)
00524 {
00525   mpz_mdiv (&rep(), &rep(), &divisor.rep());
00526 }
00527 
00528 template<> inline void
00529 scalar<MPZ>::quo (unsigned long divisor)
00530 {
00531   mpz_mdiv_ui(&rep(), &rep(), divisor);
00532 }
00533 
00534 template<> inline void
00535 scalar<MPZ>::rem (const scalar<MPZ>& divisor)
00536 {
00537   mpz_mmod(&rep(), &rep(), &divisor.rep());
00538 }
00539 
00540 template<> inline unsigned long
00541 scalar<MPZ>::rem (unsigned long divisor)
00542 {
00543   return mpz_mmod_ui(&rep(), &rep(), divisor);
00544 }
00545 
00546 template<> inline void
00547 scalar<MPZ>::sqrt ( )
00548 {
00549   mpz_sqrt(&rep(), &rep());
00550 }
00551 
00552 inline void
00553 SqrtRem (scalar<MPZ>& sqrt, scalar<MPZ>& rem, const scalar<MPZ>& b)
00554 {
00555   mpz_sqrtrem(&sqrt.rep(), &rem.rep(), &b.rep());
00556 }
00557  
00558 inline void
00559 QuoRem (scalar<MPZ>& q, scalar<MPZ>& r, const scalar<MPZ>& divdend, const scalar<MPZ>& divisor)
00560 {
00561   mpz_mdivmod(&q.rep(), &r.rep(), &divdend.rep(), &divisor.rep());
00562 }
00563 
00564 inline unsigned long
00565 QuoRem (scalar<MPZ>& q, scalar<MPZ>& r, const scalar<MPZ>& divdend, unsigned long divisor)
00566 {
00567   return mpz_mdivmod_ui(&q.rep(), &r.rep(), &divdend.rep(), divisor);
00568 }
00569 
00570 inline void
00571 DivMod (scalar<MPZ>& q, scalar<MPZ>& r, const scalar<MPZ>& divdend, const scalar<MPZ>& divisor)
00572 {
00573   mpz_divmod(&q.rep(), &r.rep(), &divdend.rep(), &divisor.rep());
00574 }
00575 
00576 inline void
00577 DivMod (scalar<MPZ>& q, scalar<MPZ>& r, const scalar<MPZ>& divdend, unsigned long divisor)
00578 {
00579   mpz_divmod_ui(&q.rep(), &r.rep(), &divdend.rep(), divisor);
00580 }
00581 
00582 inline 
00583 void ExtGCD (scalar<MPZ>& gcd, scalar<MPZ>& a, scalar<MPZ>& b, 
00584              const scalar<MPZ>& x, const scalar<MPZ>& y)
00585 {
00586   mpz_gcdext(&gcd.rep(), &a.rep(), &b.rep(), &x.rep(), &y.rep());
00587 }
00588 
00589 inline 
00590 void HalfExtGCD (scalar<MPZ>& gcd, scalar<MPZ>& a, 
00591                  const scalar<MPZ>& x, const scalar<MPZ>& y)
00592 {
00593     mpz_gcdext(&gcd.rep(), &a.rep(), 0, &x.rep(), &y.rep());
00594 }
00595 
00596 inline unsigned long BigIntToUL (const scalar<MPZ>& b)
00597 {
00598   return mpz_get_ui(&b.rep());
00599 }
00600 //-------------------------- BigIntToSL ---------------------------------
00601 inline signed long BigIntToSL (const scalar<MPZ>& b)
00602 {
00603   return mpz_get_si(&b.rep());
00604 }
00605 //-------------------------- log(...) -----------------------------------
00606 inline size_t log (const scalar<MPZ>& b)
00607 {
00608   return mpz_size(&b.rep());
00609 }
00610 
00611 inline size_t log (const scalar<MPZ>& b, int base)
00612 {
00613   assert(base >= 2 && base <= 36);
00614   return mpz_sizeinbase(&b.rep(), base);
00615 }
00616 //-------------------------- sign ---------------------------------------------
00617 inline int sign (const scalar<MPZ>& b)
00618 {
00619   if (b.rep()._mp_size == 0)
00620     return 0;
00621   else
00622     return b.rep()._mp_size > 0 ? 1 : -1;
00623 }
00624 //-------------------------- compare (...) ------------------------------------
00625 inline int compare (const scalar<MPZ>& b1, const scalar<MPZ>& b2)
00626 {
00627   return mpz_cmp(&b1.rep(), &b2.rep());
00628 }
00629 
00630 inline int compare (const scalar<MPZ>& b, unsigned long ul)
00631 {
00632   return mpz_cmp_ui(&b.rep(), ul);
00633 }
00634 
00635 inline int compare (const scalar<MPZ>& b, long sl)
00636 {
00637   return mpz_cmp_si(&b.rep(), sl);
00638 }
00639 //-------------------------- IsPositive etc. ----------------------------------
00640 inline bool IsPositive (const scalar<MPZ>& b) {
00641   return b.rep()._mp_size > 0;
00642 }
00643 
00644 inline bool IsNegative (const scalar<MPZ>& b) {
00645   return b.rep()._mp_size < 0;
00646 }
00647 
00648 inline bool IsZero (const scalar<MPZ>& b) {
00649   return b.rep()._mp_size == 0;
00650 }
00651 
00652 inline bool IsOne(const scalar<MPZ>& b) {
00653   return b.rep()._mp_size == 1 && b.rep()._mp_d[0] == 1;
00654 }
00655 
00656 inline bool IsMinusOne (const scalar<MPZ>& b) {
00657   return b.rep()._mp_size == -1 && b.rep()._mp_d[0] == 1;
00658 }
00659 
00660 inline bool IsOdd (const scalar<MPZ>& b) {
00661   return b.rep()._mp_size != 0 && (b.rep()._mp_d[0] & ((mp_limb_t) 1));
00662 }
00663 
00664 inline bool IsEven (const scalar<MPZ>& b) {
00665   return b.rep()._mp_size == 0 || (b.rep()._mp_d[0] ^ ((mp_limb_t) 0));
00666 }
00667 
00668 inline bool IsPerfectSquare (const scalar<MPZ>& b)
00669 {
00670   return mpz_perfect_square_p(&b.rep());
00671 }
00672 
00673 inline bool IsProbablyPrime (const scalar<MPZ>& b, int reps /* = 25 */)
00674 {
00675   return mpz_probab_prime_p(&b.rep(), reps);
00676 }
00677 //----------------------------------------------------------------------
00678 inline
00679 scalar<MPZ> operator << (const scalar<MPZ>& x, long int s) {
00680   scalar<MPZ> r; 
00681   if (s >= 0) mpz_mul_2exp (&r.rep(), &x.rep(), s);
00682   else mpz_div_2exp (&r.rep(), &x.rep(), -s);
00683   return r; 
00684 }
00685 //----------------------------------------------------------------------
00686 inline
00687 scalar<MPZ>& operator <<= (scalar<MPZ>& x, long int s) 
00688 {
00689   if (s >= 0) mpz_mul_2exp (&x.rep(), &x.rep(), s);
00690   else mpz_div_2exp (&x.rep(), &x.rep(), -s);
00691   return x; 
00692 }
00693 
00694 inline scalar<MPZ> Size( const scalar<MPZ> & z ) { return abs(z); };
00695 
00696 inline long int bit_size(const scalar<MPZ>& z)  {return mpz_sizeinbase(&z.rep(),2);}
00697 
00698 inline scalar<MPZ> gcd(const scalar<MPZ> & a, const scalar<MPZ> & b)
00699 {
00700   scalar<MPZ> r;
00701   mpz_gcd(&r.rep(), &a.rep(), &b.rep());
00702   return r;
00703 }
00704 
00705 inline scalar<MPZ> lcm(const scalar<MPZ> & a, const scalar<MPZ> & b)  { return (a*b)/gcd(a,b); }
00706 //--------------------------------------------------------------------
00707 inline scalar<MPZ> pow(const scalar<MPZ>& a, unsigned  n)
00708 {
00709   scalar<MPZ> r;
00710   mpz_pow_ui(&r.rep(), &a.rep(), n);
00711   return r;
00712 }
00713 
00714 inline scalar<MPZ> isqrt(const scalar<MPZ>& a)    { return sqrt(a) + 1; }
00715 
00716 //--------------------------------------------------------------------
00717 namespace let
00718 {
00719   inline void assign(scalar<MPZ>& z, char * s)   { mpz_set_str(&z.rep(), s, 10); }
00720   inline void assign(scalar<MPZ>& z, int n)      { mpz_set_si(&z.rep(),n); }
00721   inline void assign(scalar<MPZ>& z, double d )  { z = (int)d; };
00722   inline void assign(scalar<MPZ>& x, const scalar<MPZ>& r)      { mpz_set(&x.rep(),&r.rep()); }
00723   inline void assign(int& x, const scalar<MPZ>& r)       { x = mpz_get_si(&r.rep()); }
00724   inline void assign(long int& x, const scalar<MPZ>& r)  { x = mpz_get_si(&r.rep()); }
00725   inline void assign( double & r, const scalar<MPZ> & z ) { r = mpz_get_d(&z.rep()); }
00726   
00727 }
00728 
00729 //   inline double convert( const scalar<MPZ> & z, meta::As<double> ) { return z.get_d(); };
00730   inline double to_double(const scalar<MPZ>& z)   { return mpz_get_d(&z.rep()); }
00731 
00732   template<typename T,typename F> struct as_helper;
00733   template<> struct as_helper<double,scalar<MPZ> > { 
00734   static inline double cv(const scalar<MPZ>& x) {return mpz_get_d(&x.rep());}
00735 };
00736 } // namespace mmx
00737 //======================================================================
00738 #endif // //SCL_MPZ_H