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