synaps/arithm/ModP.h

00001 /*********************************************************************
00002 *      This file is part of the source code of SYNAPS kernel.        *
00003 *   Author(s): B. Mourrain, GALAAD, INRIA                            *
00004 **********************************************************************
00005 History: 
00006 $Id: ModP.h,v 1.1 2005/07/11 10:39:47 mourrain Exp $
00007 **********************************************************************/
00008 #ifndef SYNAPS_ARITHM_MODP_H
00009 #define SYNAPS_ARITHM_MODP_H
00010 //----------------------------------------------------------------------
00011 #include <iostream>
00012 #include <cstdlib>
00013 #include <cassert>
00014 #include <synaps/init.h>
00015 //----------------------------------------------------------------------
00018 __BEGIN_NAMESPACE_SYNAPS
00019 
00020 template <class T=int>
00021 struct ModP
00022 {
00023 private:
00024   T p;
00025 
00026 public:
00027   ModP(): p(0) {}
00028   ModP(int n): p(n){ assert(n>0); };
00029   ModP(const ModP<T> & z): p(z.p) {}
00030 
00031 
00032   bool equal (T   a, T  b)      {return (a-b)%p==0;} 
00033   void assign(T & r, T  a)      {r =a %p;} 
00034   void add   (T & r, T  a)      {r+=a %p;}
00035   void add   (T & r, T  a, T b) {r=(a+b) %p;}
00036   void sub   (T & r, T  a)      {r-=a %p;}
00037   void sub   (T & r, T  a, T b) {r=(a-b) %p;}
00038   void neg   (T & r, T  a)      {r=-a;}
00039   void mul   (T & r, T  a)      {r*=a; r%=p;}
00040   void mul   (T & r, T  a, T b) {r=(a*b) %p;}
00041   void div   (T & res, T  z)      
00042     {
00043       assert(z!=0 && p!=0);
00044       T a=p, b=z;
00045       b %=p; b +=p; b%=p;
00046       T r=b, u1=1,u2=0, q, inv=0;
00047       while(r!=0) 
00048         {
00049           q = a/b; 
00050           r = (a-q*b)%p; a=b; b=r;
00051           u2= (inv-q*u1)%p; inv=u1; u1=u2;
00052         }
00053       inv+=p; inv%=p;
00054       mul(res,inv);
00055     }
00056   void div   (T & r, T  a, T b) {r=a; div(r,b);}
00057 
00058   void print (std::ostream & os, const T & a) {os<<a;}
00059   void read  (std::istream & is, T& a) {is>>a;}
00060 };
00061 //----------------------------------------------------------------------
00062 
00063 __END_NAMESPACE_SYNAPS
00064 
00065 #endif // SYNAPS_ARITHM_MODP_H

SYNAPS DOCUMENTATION
logo