/* * lib_z.h * * Created on: Sep 28, 2010 * Author: anders */ #ifndef LIB_Z_H_ #define LIB_Z_H_ #include #include #define OLD 1 #if OLD #include #include "gmp.h" namespace gfan{ class Rational; class Integer { friend class Rational; mpz_t value; public: static bool isField() { return false; } Integer() { mpz_init(value); } Integer(signed long int value_) { mpz_init(value); mpz_set_si(value,value_); } Integer(Integer const & value_) { mpz_init_set(value,value_.value); } Integer(mpz_t const value_) { mpz_init_set(value,value_); } ~Integer() { mpz_clear(value); } Integer& operator=(const Integer& a) { const Integer *A=(const Integer*)&a; if (this != A) { mpz_clear(value); mpz_init_set(value, a.value); } return *this; } bool isZero()const{ return mpz_sgn(value)==0; } friend std::ostream &operator<<(std::ostream &f, Integer const &a) { void (*freefunc)(void *, size_t); mp_get_memory_functions(0,0,&freefunc); char *str=mpz_get_str(0,10,a.value); f<setGmp(v); bool ret=(mpz_fits_sint_p(v)!=0); mpz_clear(v); return ret; } int toInt()const { mpz_t v; mpz_init(v); this->setGmp(v); int ret=0; if(mpz_fits_sint_p(v)) ret=mpz_get_si(v); // else // ok=false; mpz_clear(v); return ret; } }; } #else namespace gfan{ typedef signed long int word;//processor type for integers typedef int64_t LimbWord;//memory word. Assumed to be at least as big as word typedef uint64_t uLimbWord;//memory word. Assumed to be at least as big as word const int limbSizeInBytes=8; #include struct spec64malloc{ int64_t data; bool hasLimbs() { return data&1; } word fitsMask() { return 0xc000000000000000; } void assign(word value)//assuming data fits { data=value<<1; } void alloc(int nlimbs)//one limb is added since that will tell the number of remaining limbs { int64_t temp=(int64_t)malloc((nlimbs+1)*limbSizeInBytes); assert(temp); data=temp+1; } LimbWord *limbs()//assuming that limbs exist { return (LimbWord*)(data-1); } word nlimbs()//assuming limbs exist { return (word)*limbs(); } void copy(spec64malloc b) { if(hasLimbs()) { word n2=b.nlimbs()+1; int64_t temp=(int64_t)malloc((n2)*limbSizeInBytes); assert(temp); data=temp+1; memcpy((LimbWord*)temp,limbs(),n2*limbSizeInBytes); } else { data=b.data; } } void doFree()//assuming that limbs exist { free((void*)(data-1)); } word valueToWord()//assume no limbs and that word is big enough to contain int64_t { return data>>1; } }; template struct IntegerTemplate : public spec { private: bool fits(word v) { return !((value_&fitsMask())^((value_<<1)&fitsMask)); } public: static bool isField() { return false; } IntegerTemplate() { spec.data=0; } void assignWordNoFree() { if(fits(value_)) { assign(value); } else { alloc(1); limbs()[0]=1; limbs()[1]=value_; } } IntegerTemplate(word value_) { assignWordNoFree(value_); } IntegerTemplate(IntegerTemplate const & value_) { if(value_.hasLimbs()) { copy(value_); } else data=value.data; } /* Integer(mpz_t value_) { mpz_init_set(value,value_); }*/ ~IntegerTemplate() { if(hasLimbs())doFree(); } IntegerTemplate& operator=(const IntegerTemplate& a) { if(this!=&a) { if(hasLimps())doFree(); copy(a); } return *this; } bool isZero()const{ return data==0; } friend std::ostream &operator<<(std::ostream &f, IntegerTemplate const &a) { if(hasLimps()) { LimpWord *p=limbs(); int l=*p++; for(int i=0;i Integer; }; #endif #endif /* LIB_Z_H_ */