source: git/gfanlib/gfanlib_z.h @ afbc156

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