source: git/gfanlib/gfanlib_z.h @ 91788d2

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