source: git/gfanlib/gfanlib_z.h @ 5417ff

spielwiese
Last change on this file since 5417ff was 26b713, checked in by Yue Ren <ren@…>, 11 years ago
chg: updated gfanlib package to newest version in master
  • Property mode set to 100644
File size: 7.2 KB
Line 
1/*
2 * lib_z.h
3 *
4 *  Created on: Sep 28, 2010
5 *      Author: anders
6 */
7
8#ifndef LIB_Z_H_
9#define LIB_Z_H_
10
11#include <string.h>
12#include <ostream>
13
14#define OLD 1
15#if OLD
16#include "gmp.h"
17
18namespace gfan{
19  class Rational;
20class Integer
21{
22  friend class Rational;
23  mpz_t value;
24public:
25  static bool isField()
26  {
27    return false;
28  }
29  Integer()
30  {
31    mpz_init(value);
32  }
33  Integer(signed long int value_)
34  {
35    mpz_init(value);
36    mpz_set_si(value,value_);
37  }
38  Integer(Integer const & value_)
39  {
40    mpz_init_set(value,value_.value);
41  }
42  Integer(mpz_t value_)
43  {
44    mpz_init_set(value,value_);
45  }
46  ~Integer()
47  {
48    mpz_clear(value);
49  }
50  Integer& operator=(const Integer& a)
51    {
52      const Integer *A=(const Integer*)&a;
53      if (this != A) {
54        mpz_clear(value);
55        mpz_init_set(value, a.value);
56      }
57      return *this;
58    }
59  bool isZero()const{
60    return mpz_sgn(value)==0;
61  }
62  friend std::ostream &operator<<(std::ostream &f, Integer const &a)
63  {
64    void (*freefunc)(void *, size_t);
65    mp_get_memory_functions(0,0,&freefunc);
66    char *str=mpz_get_str(0,10,a.value);
67    f<<str;
68    freefunc(str,strlen(str)+1);
69    return f;
70  }
71  Integer& operator+=(const Integer& a)
72    {
73      mpz_add(value,value,a.value);
74      return *this;
75    }
76  Integer& operator-=(const Integer& a)
77    {
78      mpz_sub(value,value,a.value);
79      return *this;
80    }
81  Integer& operator*=(const Integer& a)
82    {
83      mpz_mul(value,value,a.value);
84      return *this;
85    }
86  Integer& operator/=(const Integer& a)
87    {
88      mpz_div(value,value,a.value);
89      return *this;
90    }
91  friend Integer operator-(const Integer &b)
92  {
93    Integer ret;
94    ret-=b;
95    return ret;
96  }
97  Integer operator+(const Integer &a)const
98  {
99    Integer ret(*this);
100    ret+=a;
101    return ret;
102  }
103  Integer operator-(const Integer &a)const
104  {
105    Integer ret(*this);
106    ret-=a;
107    return ret;
108  }
109  Integer operator*(const Integer &a)const
110  {
111    Integer ret(*this);
112    ret*=a;
113    return ret;
114  }
115  Integer operator/(const Integer &a)const
116  {
117    Integer ret(*this);
118    ret/=a;
119    return ret;
120  }
121  void madd(const Integer &a,const Integer &b)
122    {
123      mpz_t temp;
124      mpz_init(temp);
125      mpz_mul(temp,a.value,b.value);
126      mpz_add(value,value,temp);
127      mpz_clear(temp);
128    }
129  bool operator<(const Integer &a)const
130  {
131    return mpz_cmp(value,a.value)<0;
132  }
133  bool operator==(const Integer &a)const
134  {
135    return mpz_cmp(value,a.value)==0;
136  }
137  bool operator!=(const Integer &a)const
138  {
139    return mpz_cmp(value,a.value)!=0;
140  }
141  int sign()const
142  {
143    return mpz_sgn(value);
144  }
145  static Integer gcd(Integer const &a, Integer const &b, Integer &s, Integer &t)
146  {
147    mpz_t r;
148    mpz_init(r);
149    mpz_gcdext(r,s.value,t.value,a.value,b.value);
150    Integer ret(r);
151    mpz_clear(r);
152    return ret;
153  }
154  /**
155   * Assigns the value to z. z must have been initialized as a gmp variable.
156   */
157  void setGmp(mpz_t z)const
158  {
159    mpz_set(z,value);
160  }
161  /**
162   * Returns a value which is useful for computing hash functions.
163   */
164  signed long int hashValue()const
165  {
166    return mpz_get_si(value);
167  }
168  bool fitsInInt()const
169  {
170    mpz_t v;
171    mpz_init(v);
172    this->setGmp(v);
173    bool ret=(mpz_fits_sint_p(v)!=0);
174    mpz_clear(v);
175    return ret;
176  }
177  int toInt()const
178  {
179    mpz_t v;
180    mpz_init(v);
181    this->setGmp(v);
182    int ret=0;
183    if(mpz_fits_sint_p(v))
184      ret=mpz_get_si(v);
185//    else
186//      ok=false;
187    mpz_clear(v);
188    return ret;
189  }
190};
191
192
193}
194
195#else
196namespace gfan{
197  typedef signed long int word;//processor type for integers
198  typedef int64_t LimbWord;//memory word. Assumed to be at least as big as word
199  typedef uint64_t uLimbWord;//memory word. Assumed to be at least as big as word
200  const int limbSizeInBytes=8;
201#include <stdint.h>
202  struct spec64malloc{
203    int64_t data;
204    bool hasLimbs()
205    {
206      return data&1;
207    }
208    word fitsMask()
209    {
210      return 0xc000000000000000;
211    }
212    void assign(word value)//assuming data fits
213    {
214      data=value<<1;
215    }
216    void alloc(int nlimbs)//one limb is added since that will tell the number of remaining limbs
217    {
218      int64_t temp=(int64_t)malloc((nlimbs+1)*limbSizeInBytes);
219      assert(temp);
220      data=temp+1;
221    }
222    LimbWord *limbs()//assuming that limbs exist
223    {
224      return (LimbWord*)(data-1);
225    }
226    word nlimbs()//assuming limbs exist
227    {
228      return (word)*limbs();
229    }
230    void copy(spec64malloc b)
231    {
232      if(hasLimbs())
233        {
234          word n2=b.nlimbs()+1;
235          int64_t temp=(int64_t)malloc((n2)*limbSizeInBytes);
236          assert(temp);
237
238          data=temp+1;
239          memcpy((LimbWord*)temp,limbs(),n2*limbSizeInBytes);
240        }
241      else
242        {
243          data=b.data;
244        }
245    }
246    void doFree()//assuming that limbs exist
247    {
248      free((void*)(data-1));
249    }
250    word valueToWord()//assume no limbs and that word is big enough to contain int64_t
251    {
252      return data>>1;
253    }
254  };
255  template <struct spec> struct IntegerTemplate : public spec
256  {
257  private:
258    bool fits(word v)
259    {
260      return !((value_&fitsMask())^((value_<<1)&fitsMask));
261    }
262  public:
263    static bool isField()
264    {
265      return false;
266    }
267    IntegerTemplate()
268    {
269      spec.data=0;
270    }
271    void assignWordNoFree()
272    {
273      if(fits(value_))
274        {
275          assign(value);
276        }
277      else
278        {
279          alloc(1);
280          limbs()[0]=1;
281          limbs()[1]=value_;
282        }
283    }
284    IntegerTemplate(word value_)
285    {
286      assignWordNoFree(value_);
287    }
288    IntegerTemplate(IntegerTemplate const & value_)
289    {
290      if(value_.hasLimbs())
291        {
292          copy(value_);
293        }
294      else
295        data=value.data;
296    }
297/*    Integer(mpz_t value_)
298    {
299      mpz_init_set(value,value_);
300    }*/
301    ~IntegerTemplate()
302    {
303      if(hasLimbs())doFree();
304    }
305    IntegerTemplate& operator=(const IntegerTemplate& a)
306      {
307        if(this!=&a)
308          {
309            if(hasLimps())doFree();
310            copy(a);
311          }
312        return *this;
313      }
314    bool isZero()const{
315      return data==0;
316    }
317    friend std::ostream &operator<<(std::ostream &f, IntegerTemplate const &a)
318    {
319      if(hasLimps())
320        {
321          LimpWord *p=limbs();
322          int l=*p++;
323          for(int i=0;i<l;i++)
324            f<<":"<<p[i];
325        }
326      else
327        {
328          f<<valueToWord();
329        }
330      return f;
331    }
332    LimbWord signExtension(LimbWord a)
333    {
334      return 0-(a<0);
335    }
336    void addWordToLimbs(word v)
337    {
338      int n=nlimbs();
339      LimbWord V=v;
340      LimbWord *p=limbs()+1;
341      LimbWord s=signExtension(V);
342      for(int i=0;i<n;i++)
343        {
344          LimbWord r=V+*p;
345          bool carry=(uLimbWord)r<(uLimbWord)V;
346          V=carry+s;
347        }
348
349    }
350
351
352    IntegerTemplate& operator+=(const IntegerTemplate& a)
353      {
354        if(hasLimbs()||a.hasLimbs())
355          {
356            if(!hasLimbs())
357              {
358
359              }
360            else
361              {
362              }
363
364          }
365        else
366          {
367            word C=valueToWord();
368            word A=a.valueToWord();
369            word D=A+C;
370            assignWordNoFree(D);
371          }
372        return *this;
373      }
374
375  };
376
377  typedef IntegerTemplate<spec64malloc> Integer;
378};
379#endif
380
381#endif /* LIB_Z_H_ */
382
Note: See TracBrowser for help on using the repository browser.