source: git/gfanlib/gfanlib_z.h @ 491e80

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