realroot_doc 0.1.1
|
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