00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef SYNAPS_ARITHM_SCL_H
00012 #define SYNAPS_ARITHM_SCL_H
00013
00014 #ifndef NDEBUG
00015 #include <cassert>
00016 #endif
00017
00018
00019 #include <cstdio>
00020 #include <gmp.h>
00021 #include <synaps/init.h>
00022 #include <synaps/arithm/REF.h>
00023 #include <synaps/base/shared_object.h>
00024
00025
00026
00027 __BEGIN_NAMESPACE_SYNAPS
00028
00029 #define WITH_TEMP_EXP
00030
00033 template<class T> struct Scl
00034 {
00035 public:
00036 #ifdef WITH_TEMP_EXP
00037 T data;
00038 inline T & rep() {return (data);}
00039 inline const T & rep() const {return (data);}
00040 #else
00041 shared_object<T> data;
00042 T & rep() {return (*data);}
00043 const T & rep() const {return (*data);}
00044 #endif
00045 Scl ();
00046 Scl (const Scl<T>& b);
00047 Scl (double d);
00048 Scl (signed long sl);
00049 Scl (unsigned long ul);
00050 Scl (int si);
00051 Scl (const char* string, unsigned int b=10);
00052 Scl (const T & r);
00053
00054 template<class S>
00055 Scl(const VAL<S> & P) {this->init();let::assign(*this,P.rep());}
00056
00057 ~Scl () {}
00058
00059 bool operator == (const Scl<T>& rhs) const;
00060 bool operator != (const Scl<T>& rhs) const;
00061 bool operator > (const Scl<T>& rhs) const;
00062 bool operator >= (const Scl<T>& rhs) const;
00063 bool operator < (const Scl<T>& rhs) const;
00064 bool operator <= (const Scl<T>& rhs) const;
00065
00066 bool operator == (long sl) const;
00067 bool operator != (long sl) const;
00068 bool operator > (long sl) const;
00069 bool operator >= (long sl) const;
00070 bool operator < (long sl) const;
00071 bool operator <= (long sl) const;
00072
00073 bool operator == (int si) const;
00074 bool operator != (int si) const;
00075 bool operator > (int si) const;
00076 bool operator >= (int si) const;
00077 bool operator < (int si) const;
00078 bool operator <= (int si) const;
00079
00080 bool operator == (unsigned long ul) const;
00081 bool operator != (unsigned long ul) const;
00082 bool operator > (unsigned long ul) const;
00083 bool operator >= (unsigned long ul) const;
00084 bool operator < (unsigned long ul) const;
00085 bool operator <= (unsigned long ul) const;
00086
00087
00088
00089 Scl<T>& operator = (const Scl<T>& rhs);
00090 Scl<T>& operator += (const Scl<T>& rhs);
00091 Scl<T>& operator -= (const Scl<T>& rhs);
00092 Scl<T>& operator *= (const Scl<T>& rhs);
00093 Scl<T>& operator /= (const Scl<T>& rhs);
00094 Scl<T>& operator %= (const Scl<T>& rhs);
00095
00096 Scl<T>& operator = (int rhs);
00097 Scl<T>& operator += (int rhs);
00098 Scl<T>& operator -= (int rhs);
00099 Scl<T>& operator *= (int rhs);
00100 Scl<T>& operator /= (int rhs);
00101 Scl<T>& operator %= (int rhs);
00102
00103 Scl<T>& operator = (unsigned long rhs);
00104 Scl<T>& operator += (unsigned long rhs);
00105 Scl<T>& operator -= (unsigned long rhs);
00106 Scl<T>& operator *= (unsigned long rhs);
00107 Scl<T>& operator /= (unsigned long rhs);
00108 Scl<T>& operator %= (unsigned long rhs);
00109
00110 Scl<T>& operator *= (double rhs);
00111 Scl<T>& operator += (double rhs);
00112
00113 Scl<T>& operator = (long rhs);
00114 Scl<T>& operator += (long rhs);
00115 Scl<T>& operator -= (long rhs);
00116 Scl<T>& operator *= (long rhs);
00117 Scl<T>& operator /= (long rhs);
00118
00119
00120 template<class S>
00121 Scl<T>& operator = (const VAL<S> & x)
00122 {
00123 let::assign(*this,x.rep());return *this;
00124 }
00125 template<class S>
00126 Scl<T>& operator += (const VAL<S> & x)
00127 {Scl<T> tmp(x);*this+=tmp;return *this;}
00128 template<class S>
00129 Scl<T>& operator -= (const VAL<S> & x)
00130 {Scl<T> tmp(x); *this-=tmp;return *this;}
00131 template<class S> Scl<T>& operator *= (const VAL<S> & x)
00132 {Scl<T> tmp(x); *this*=tmp;return *this;}
00133 template<class S> Scl<T>& operator /= (const VAL<S> & x)
00134 {Scl<T> tmp(x); *this/=tmp;return *this;}
00135 template<class S> Scl<T>& operator %= (const VAL<S> & x)
00136 {Scl<T> tmp(x); *this%=tmp;return *this;}
00137
00138
00139 void operator ++ ( );
00140 void operator -- ( );
00141
00142 void Div2Exp (unsigned long exponent_of_2);
00143 void GCD (const Scl<T>& b2);
00144 void Mod2Exp (unsigned long exponent_of_2);
00145 void Mul2Exp (unsigned long exponent_of_2);
00146 void PowMod (const Scl<T>& exp, const Scl<T>& m);
00147 void PowMod (unsigned long exp, const Scl<T>& m);
00148 void abs ( );
00149 void factorial (unsigned long n);
00150 Scl<T>& negate ( );
00151 Scl<T>& pow (unsigned long exp);
00152 Scl<T>& pow (unsigned long base, unsigned long exp);
00153 void quo (const Scl<T>& divisor);
00154 void quo (unsigned long divisor);
00155 void rem (const Scl<T>& divisor);
00156 unsigned long rem (unsigned long divisor);
00157 void sqrt ( );
00158
00159 private:
00160 void init();
00161 };
00162
00163
00164
00165
00166 #ifdef WITH_TEMP_EXP
00167 template <class R> inline
00168 VAL<OP<'+',Scl<R>,Scl<R> > > operator+(const Scl<R> & a, const Scl<R> & b)
00169 {
00170 return VAL<OP<'+',Scl<R>,Scl<R> > >(OP<'+',Scl<R>,Scl<R> >(a,b));
00171 }
00172
00173 template <class R> inline
00174 VAL<OP<'-',Scl<R>,Scl<R> > > operator-(const Scl<R> & a, const Scl<R> & b)
00175 {
00176 return VAL<OP<'-',Scl<R>,Scl<R> > >(OP<'-',Scl<R>,Scl<R> >(a,b));
00177 }
00178
00179
00180 template <class R> inline
00181 VAL<OP<'*',Scl<R>,Scl<R> > > operator*(const Scl<R> & a, const Scl<R> & b)
00182 {
00183 return VAL<OP<'*',Scl<R>,Scl<R> > >(OP<'*',Scl<R>,Scl<R> >(a,b));
00184 }
00185
00186
00187 template <class R> inline
00188 VAL<OP<'/',Scl<R>,Scl<R> > > operator/(const Scl<R> & a, const Scl<R> & b)
00189 {
00190 return VAL<OP<'/',Scl<R>,Scl<R> > >(OP<'/',Scl<R>,Scl<R> >(a,b));
00191 }
00192
00193
00194 template <class R> inline
00195 VAL<OP<'%',Scl<R>,Scl<R> > > operator%(const Scl<R> & a, const Scl<R> & b)
00196 {
00197 return VAL<OP<'%',Scl<R>,Scl<R> > >(OP<'%',Scl<R>,Scl<R> >(a,b));
00198 }
00199
00200 #endif
00201
00202 template<class T> inline
00203 Scl<T> operator - (const Scl<T>& b)
00204 {
00205 Scl<T> r(b); return (r.negate());
00206 }
00207
00208 template<class T> Scl<T>& operator + (const Scl<T>& b, unsigned long ul);
00209 template<class T> Scl<T>& operator - (const Scl<T>& b, unsigned long ul);
00210 template<class T> Scl<T>& operator * (const Scl<T>& b, unsigned long ul);
00211 template<class T> Scl<T>& operator / (const Scl<T>& b, unsigned long ul);
00212 template<class T> Scl<T>& operator % (const Scl<T>& b, unsigned long ul);
00213 template<class T> Scl<T>& operator + (unsigned long ul, const Scl<T>& b);
00214 template<class T> Scl<T>& operator * (unsigned long ul, const Scl<T>& b);
00215 template<class T> Scl<T>& operator + (const Scl<T>& b, long sl);
00216 template<class T> Scl<T>& operator - (const Scl<T>& b, long sl);
00217 template<class T> Scl<T>& operator * (const Scl<T>& b, long sl);
00218 template<class T> Scl<T>& operator / (const Scl<T>& b, long sl);
00219 template<class T> Scl<T>& operator % (const Scl<T>& b, long sl);
00220 template<class T> Scl<T>& operator + (long sl, const Scl<T>& b);
00221 template<class T> Scl<T>& operator * (long sl, const Scl<T>& b);
00222 template<class T> Scl<T>& operator * (double d, const Scl<T>& b);
00223
00224 template<class T> Scl<T>& Div2Exp (const Scl<T>& b,
00225 unsigned long exponent_of_2);
00226 template<class T> Scl<T>& GCD (const Scl<T>& b1, const Scl<T>& b2);
00227 template<class T> Scl<T>& gcd (const Scl<T>& b1, const Scl<T>& b2);
00228 template<class T> Scl<T>& Mod2Exp (const Scl<T>& b,
00229 unsigned long exponent_of_2);
00230 template<class T> Scl<T>& Mul2Exp (const Scl<T>& b, unsigned long exponent_of_2);
00231 template<class T> Scl<T>& PowMod (const Scl<T>& b, const Scl<T>& exp, const Scl<T>& m);
00232 template<class T> Scl<T>& PowMod (const Scl<T>& b, unsigned long exp,
00233 const Scl<T>& m);
00234 template<class T> Scl<T> abs (const Scl<T>& b);
00235
00236 template<class T> Scl<T> pow (const Scl<T>& base, unsigned long exp);
00237 template<class T> Scl<T>& quo (const Scl<T>& dividend,
00238 const Scl<T>& divisor);
00239 template<class T> Scl<T>& quo (const Scl<T>& dividend,
00240 unsigned long divisor);
00241 template<class T> Scl<T>& rem (const Scl<T>& dividend,
00242 const Scl<T>& divisor);
00243 template<class T> Scl<T> sqrt (const Scl<T>& b);
00244 template<class T> unsigned long rem (const Scl<T>& b, unsigned long divisor);
00245
00246 template<class T> Scl<T>& BigIntFactorial (unsigned long n);
00247
00248
00249
00250
00251
00252 #define NO_NRV 1
00253 #if defined(__GNUG__) && !defined(NO_NRV)
00254 #define NRVAL(name) return name
00255 #define NRCODE(code) code
00256 #define NONRCODE(code)
00257 #else
00258 #define NRVAL(name)
00259 #define NRCODE(code)
00260 #define NONRCODE(code) code
00261 #endif
00262
00263 #define OPCODE(a, b, op) Scl<T>& r =*new Scl<T>(a); return (r op b);
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 template<class T> inline
00298 Scl<T>& operator + (const Scl<T>& b, int ul)
00299 {
00300 OPCODE(b,ul,+=)
00301 }
00302 template<class T> inline
00303 Scl<T>& operator + (const Scl<T>& b, unsigned long ul)
00304 {
00305 OPCODE(b,ul,+=)
00306 }
00307
00308 template<class T> inline
00309 Scl<T>& operator - (const Scl<T>& b, unsigned long ul)
00310 {
00311 OPCODE(b,ul,-=)
00312 }
00313
00314 template<class T> inline Scl<T>&
00315 operator * (const Scl<T>& b, unsigned long ul)
00316 {
00317 OPCODE(b,ul,*=)
00318 }
00319
00320 template<class T> inline Scl<T>&
00321 operator / (const Scl<T>& b, unsigned long ul)
00322 {
00323 OPCODE(b,ul,/=)
00324 }
00325
00326 template<class T> inline
00327 Scl<T>& operator % (const Scl<T>& b, unsigned long ul)
00328 {
00329 OPCODE(b,ul,%=)
00330 }
00331
00332
00333 template<class T> inline
00334 Scl<T>& operator + (unsigned long ul, const Scl<T>& b)
00335 {
00336 return b + ul;
00337 }
00338
00339 template<class T> inline
00340 Scl<T>& operator * (unsigned long ul, const Scl<T>& b)
00341 {
00342 return b * ul;
00343 }
00344
00345 template<class T> inline
00346 Scl<T>& operator + (const Scl<T>& b, long sl)
00347 {
00348 OPCODE(b,sl,+=)
00349 }
00350
00351
00352 template<class T> inline
00353 Scl<T>& operator - (const Scl<T>& b, long sl) NRVAL(r(b))
00354 {
00355 OPCODE(b,sl,-=)
00356 }
00357
00358 template<class T> inline
00359 Scl<T>& operator * (const Scl<T>& b, int sl) NRVAL(r(b))
00360 {
00361 OPCODE(b,sl,*=)
00362 }
00363
00364 template<class T> inline
00365 Scl<T>& operator * (const Scl<T>& b, long sl) NRVAL(r(b))
00366 {
00367 OPCODE(b,sl,*=)
00368 }
00369
00370 template<class T> inline
00371 Scl<T>& operator / (const Scl<T>& b, long sl) NRVAL(r(b))
00372 {
00373 OPCODE(b,sl,/=)
00374 }
00375
00376 template<class T> inline Scl<T>&
00377 operator % (const Scl<T>& b, long sl) NRVAL(r(b))
00378 {
00379 OPCODE(b,sl,%=)
00380 }
00381
00382
00383
00384 template<class T> inline
00385 Scl<T>& operator + (long sl, const Scl<T>& b)
00386 {
00387 return b + sl;
00388 }
00389
00390 template<class T> inline
00391 Scl<T>& operator * (long sl, const Scl<T>& b)
00392 {
00393 return b * sl;
00394 }
00395
00396
00397 template<class T> inline
00398 Scl<T>& Div2Exp (const Scl<T>& b, unsigned long exponent_of_2) NRVAL(r(b))
00399 {
00400 NRCODE(r.Div2Exp(exponent_of_2);)
00401 NONRCODE(Scl<T> r(b); r.Div2Exp(exponent_of_2); return r;)
00402 }
00403
00404 template<class T> inline
00405 Scl<T>& GCD (const Scl<T>& b1, const Scl<T>& b2) NRVAL(r(b1))
00406 {
00407 NRCODE(r.GCD(b2);)
00408 NONRCODE(Scl<T> r(b1); r.GCD(b2); return r;)
00409 }
00410
00411 template<class T> inline
00412 Scl<T>& gcd (const Scl<T>& b1, const Scl<T>& b2) NRVAL(r(b1))
00413 {
00414 NRCODE(r.GCD(b2);)
00415 NONRCODE(Scl<T> r(b1); r.GCD(b2); return r;)
00416 }
00417
00418 template<class T> inline
00419 Scl<T>& Mod2Exp (const Scl<T>& b, unsigned long exponent_of_2) NRVAL(r(b))
00420 {
00421 NRCODE(r.Mod2Exp(exponent_of_2);)
00422 NONRCODE(Scl<T> r(b); r.Mod2Exp(exponent_of_2); return r;)
00423 }
00424
00425 template<class T> inline
00426 Scl<T>& Mul2Exp (const Scl<T>& b, unsigned long exponent_of_2) NRVAL(r(b))
00427 {
00428 NRCODE(r.Mul2Exp(exponent_of_2);)
00429 NONRCODE(Scl<T> r(b); r.Mul2Exp(exponent_of_2); return r;)
00430 }
00431
00432 template<class T> inline
00433 Scl<T>& PowMod (const Scl<T>& b, const Scl<T>& exp, const Scl<T>& m) NRVAL(r(b))
00434 {
00435 NRCODE(r.PowMod(exp, m);)
00436 NONRCODE(Scl<T> r(b); r.PowMod(exp,m); return r;)
00437 }
00438
00439 template<class T> inline
00440 Scl<T>& PowMod (const Scl<T>& b, unsigned long exp, const Scl<T>& m) NRVAL(r(b))
00441 {
00442 NRCODE(r.PowMod(exp, m);)
00443 NONRCODE(Scl<T> r(b); r.PowMod(exp,m); return r;)
00444 }
00445
00446
00447 template <class T> inline
00448 Scl<T> abs (const Scl<T>& b) NRVAL(r(b))
00449 {
00450 NRCODE(r.abs();)
00451 NONRCODE(Scl<T> r(b); r.abs(); return r;)
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461 template<class T> inline
00462 Scl<T> pow (const Scl<T>& base, unsigned long exp) NRVAL(r(base))
00463 {
00464 NRCODE(r.pow(exp);)
00465 NONRCODE(Scl<T> r(base); r.pow(exp); return r;)
00466 }
00467
00468 template<class T> inline
00469 Scl<T>& quo (const Scl<T>& dividend, const Scl<T>& divisor) NRVAL(r(dividend))
00470 {
00471 NRCODE(r.quo(divisor);)
00472 NONRCODE(Scl<T> r(dividend); r.quo(divisor); return r;)
00473 }
00474
00475 template<class T> inline
00476 Scl<T>& quo (const Scl<T>& dividend, unsigned long divisor) NRVAL(r(dividend))
00477 {
00478 NRCODE(r.quo(divisor);)
00479 NONRCODE(Scl<T> r(dividend); r.quo(divisor); return r;)
00480 }
00481
00482 template<class T> inline
00483 Scl<T>& rem (const Scl<T>& dividend, const Scl<T>& divisor) NRVAL(r(dividend))
00484 {
00485 NRCODE(r.rem(divisor);)
00486 NONRCODE(Scl<T> r(dividend); r.rem(divisor); return r;)
00487 }
00488
00489 template<class T> inline
00490 Scl<T> sqrt (const Scl<T>& b) NRVAL(r(b))
00491 {
00492 NRCODE(r.sqrt();)
00493 NONRCODE(Scl<T> r(b); r.sqrt(); return r;)
00494 }
00495
00496 template<class T> inline
00497 unsigned long rem (const Scl<T>& b, unsigned long divisor)
00498 {
00499 Scl<T> r(b);
00500 return r.rem(divisor);
00501 }
00502
00503 template<class T> inline
00504 Scl<T>& BigIntFactorial (unsigned long n) NRVAL(r)
00505 {
00506 NRCODE(r.factorial(n);)
00507 NONRCODE(Scl<T> r; r.factorial(n); return r;)
00508 }
00509
00510 template<class T> inline
00511 Scl<T>& BigIntPow (unsigned long base, unsigned long exp) NRVAL(r)
00512 {
00513 NRCODE(r.pow(base, exp);)
00514 NONRCODE(Scl<T> r; r.pow(base, exp); return r;)
00515 }
00516
00517 template<class T>
00518 Scl<T> Size(const Scl<T> & r)
00519 {
00520 return abs(r);
00521 }
00522
00523 #undef NRVAL
00524 #undef NRCODE
00525 #undef NONRCODE
00526
00527
00528 __END_NAMESPACE_SYNAPS
00529
00530 #endif // SYNAPS_ARITHM_SCL_H
00531
00532