Debian's int128 patch, with the use of abseil made unconditional. diff --git a/Makefile b/Makefile index 1d5fad9..79fce9d 100644 --- a/Makefile +++ b/Makefile @@ -166,6 +166,8 @@ SYMMETRICTRAVERSAL_FLAGS = -fno-guess-branch-probability PLATFORM_LINKOPTIONS = -rdynamic -ltbb endif +PLATFORM_LINKOPTIONS += -labsl_int128 + #OPTFLAGS = -O2 -DGMPRATIONAL -DNDEBUG # Note that gcc produces wrong code with -O3 # OPTFLAGS = -DGMPRATIONAL -Wuninitialized -O3 -fno-omit-frame-pointer -fdelete-null-pointer-checks -fno-inline-functions -fno-inline-small-functions#-fno-common #-fno-inline-functions #-D_GLIBCXX_DEBUG #-O2 #-O3 -fno-guess-branch-probability #-DNDEBUG diff --git a/src/app_test.cpp b/src/app_test.cpp index 4a91102..797e26c 100644 --- a/src/app_test.cpp +++ b/src/app_test.cpp @@ -766,14 +766,14 @@ int testGfanLib() std::cerr<<"Digits:"<::digits<<"\n"; std::cerr<<"Digits:"<::digits<<"\n"; std::cerr<<"Digits:"<::digits<<"\n"; - std::cerr<<"Digits:"<::digits<<"\n"; + std::cerr<<"Digits:"<::digits<<"\n"; { - __int128 t=0; - __int128 A=2; - __int128 s=-4; - __int128 B=1; + absl::int128 t=0; + absl::int128 A=2; + absl::int128 s=-4; + absl::int128 B=1; B=(B<<127)+3; std::cerr<<"---B\n"; std::cerr< #include "gfanlib_frequencytable.h" +#include + namespace gfan{ - /* We would like to use std::make_unsigned<> but that does not necessarily work for 128 bit integers. Therefore we define: */ template struct MyMakeUnsigned; template <> struct MyMakeUnsigned{typedef uint32_t type;}; template <> struct MyMakeUnsigned{typedef uint64_t type;}; - template <> struct MyMakeUnsigned<__int128>{typedef unsigned __int128 type;}; +#if __SIZEOF_LONG__ == 8 + template <> struct MyMakeUnsigned{typedef unsigned long long int type;}; +#endif + template <> struct MyMakeUnsigned{typedef absl::uint128 type;}; class MVMachineIntegerOverflow: public std::exception { @@ -52,14 +56,14 @@ extern IntegerConversionException IntegerConversionException; // If there is support for operator<< on 128 bit values, then the following 6 procedures can be simplified. -static std::string toStr(__int128_t b) +static std::string toStr(absl::int128 b) { std::stringstream s; s<<"["<>64)<<":"<>64)<<":"<(lo_)), + hi(hi_) + { + } + my256s(absl::uint128 lo_,absl::int128 hi_): + lo(static_cast(lo_)), + hi(hi_) + { + } + my256s(absl::int128 lo_,absl::uint128 hi_): + lo(lo_), + hi(static_cast(hi_)) + { + } my256s operator+(my256s b) { - __uint128_t newLo=lo+b.lo; - bool carry=newLo<__uint128_t(lo); + absl::uint128 newLo=lo+b.lo; + bool carry=newLo=0 && i<=127))std::cerr<<"i"<=0 && i<=127); - __uint128_t carry=i?(__uint128_t(lo))>>(128-i):0; + absl::uint128 carry=i?(absl::uint128(lo))>>(128-i):0; return my256s(lo<>(int i)const { assert(i>=0 && i<=127); -// __uint128_t carry=(__uint128_t(hi))<<(128-i); - __uint128_t carry=i?(__uint128_t(hi))<<(128-i):0;// a shift of 128 is undefined according to standard +// absl::uint128 carry=(absl::uint128(hi))<<(128-i); + absl::uint128 carry=i?(absl::uint128(hi))<<(128-i):0;// a shift of 128 is undefined according to standard // std::cerr<<"carry"<>i)+carry,hi>>i); + my256s r((absl::uint128(lo)>>i)+carry,hi>>i); // std::cerr<<"Shift"<>"<b.hi)return false; - return ((__uint128_t)lo)<=((__uint128_t)b.lo); + return ((absl::uint128)lo)<=((absl::uint128)b.lo); } bool operator<(my256s b)const { if(hib.hi)return false; - return ((__uint128_t)lo)<((__uint128_t)b.lo); + return ((absl::uint128)lo)<((absl::uint128)b.lo); } - bool operator<=(__int128_t b)const + bool operator<=(absl::int128 b)const { return *this<=my256s(b); } @@ -167,7 +186,7 @@ public: my256s temp(~lo,~hi); return temp+my256s(1,0); } - explicit operator __int128()const + explicit operator absl::int128()const { return lo; } @@ -175,7 +194,7 @@ public: class my256u{ public: - __int128_t lo,hi; + absl::int128 lo,hi; my256u(my256s const &a): lo(a.lo), hi(a.hi) @@ -187,21 +206,21 @@ public: } bool operator<=(my256s const &b)//full implementation not required as this simulates a cast to unsigned and a comparison. { - if((__uint128_t)hi<(__uint128_t)b.hi)return true; - if((__uint128_t)hi>(__uint128_t)b.hi)return false; - return ((__uint128_t)lo)<=((__uint128_t)b.lo); + if((absl::uint128)hi<(absl::uint128)b.hi)return true; + if((absl::uint128)hi>(absl::uint128)b.hi)return false; + return ((absl::uint128)lo)<=((absl::uint128)b.lo); } bool operator<(my256s const &b)//full implementation not required as this simulates a cast to unsigned and a comparison. { - if((__uint128_t)hi<(__uint128_t)b.hi)return true; - if((__uint128_t)hi>(__uint128_t)b.hi)return false; - return ((__uint128_t)lo)<((__uint128_t)b.lo); + if((absl::uint128)hi<(absl::uint128)b.hi)return true; + if((absl::uint128)hi>(absl::uint128)b.hi)return false; + return ((absl::uint128)lo)<((absl::uint128)b.lo); } my256u operator<<(int i)const { assert(i>=0 && i<=127); - __uint128_t carry=i?(__uint128_t(lo))>>(128-i):0; - return my256s(lo<>(128-i):0; + return my256s(lo<>64,y),0); @@ -230,7 +260,7 @@ static my256u unsignedProd128(__uint128_t x,__uint128_t y) return a+(b<<64)+(c<<64)+(d<<128); } -static my256s extMul(__int128_t a, __int128_t b) +static my256s extMul(absl::int128 a, absl::int128 b) { // std::cerr<<"mul"<::digits/2-2))-1}; + static constexpr word halfBound{(word{1}<<(std::numeric_limits::digits/2-2))-1}; // In the code products of CircuitTableIntPOD objects are summed. To avoid overflows one of the factors must "fit in half" and the "number of summands" may not exceed a certain number. The bounds are specified in the following functions: bool fitsInHalf()const{return v>-halfBound && v(v);}//WHAT SHOULD HAPPEN TO THIS FUNCTION? friend std::ostream &operator<<(std::ostream &f, CircuitTableIntPOD const &a){f<extend();t+=extendedMultiplication(a,b);*this=t.castToSingle();return *this;} @@ -548,8 +578,8 @@ public: int D=std::numeric_limits::digits; if(D==0){D=127;}//fixes bug in gcc-8.1 bool doesOverflow=(((word)t.v)==(word{1}<<(D-1)));// What is the purpose of this line. Do we really want to subtract 1? That seems wrong since word is signed. Look at comment below - longword min64=0; - longword max64=0; + longword min64=static_cast(0); + longword max64=static_cast(0); for(int i=0;i::digits; if(D==0){D=127;}//fixes bug in gcc-8.1 bool doesOverflow=false;//(((word)t.v)==(word{1}<<(D-1)));// What is the purpose of this line? t is not defined. Do we really want to subtract 1? That seems wrong since word is signed. Look at comment below - longword min64=0; - longword max64=0; + longword min64=static_cast(0); + longword max64=static_cast(0); for(int i=0;i CircuitTableInt32POD; -typedef CircuitTableIntPOD CircuitTableInt64POD; -typedef CircuitTableIntPOD<__int128_t,my256s> CircuitTableInt128POD; +typedef CircuitTableIntPOD CircuitTableInt64POD; +typedef CircuitTableIntPOD CircuitTableInt128POD; static bool hasPod(class CircuitTalbeInt32 *c){return true;} static bool hasPod(class CircuitTalbeInt64 *c){return true;} @@ -737,20 +766,20 @@ template<> inline CircuitTableIntPOD CircuitTableIntPOD inline CircuitTableIntPOD CircuitTableIntPOD::Double::castToSingle()const//casts and checks precission +template<> inline CircuitTableIntPOD CircuitTableIntPOD::Double::castToSingle()const//casts and checks precission { if(v>=0x7fffffffffffffff || -v>=0x7fffffffffffffff) throw MVMachineIntegerOverflow; CircuitTableIntPOD ret; - ret.v=v; + ret.v=static_cast(v); return ret; } -template<> inline CircuitTableIntPOD<__int128_t,my256s> CircuitTableIntPOD<__int128_t,my256s>::Double::castToSingle()const//casts and checks precission +template<> inline CircuitTableIntPOD CircuitTableIntPOD::Double::castToSingle()const//casts and checks precission { // DANGER !!! //if(v>=0x7fffffffffffffffffffffffffffffff || -v>=0x7fffffffffffffffffffffffffffffff) throw MVMachineIntegerOverflow; CircuitTableIntPOD ret; - ret.v=__int128(v); + ret.v=absl::int128(v); return ret; } @@ -787,7 +816,8 @@ public: static bool POD2; CircuitTableInt128()noexcept{v=0;} CircuitTableInt128(CircuitTableInt128POD const &m){v=m.v;} - CircuitTableInt128(__int128_t val){v=val;} + CircuitTableInt128(absl::int128 val){v=val;} + CircuitTableInt128(int val){v=val;} CircuitTableInt128(std::string const&s){ int64_t proxy; std::istringstream a(s); a>>proxy; diff --git a/src/gfanlib_tableau.h b/src/gfanlib_tableau.h index d2ced06..c6d2e14 100644 --- a/src/gfanlib_tableau.h +++ b/src/gfanlib_tableau.h @@ -335,8 +335,8 @@ template class Tableau{ { combinedMatrix=Matrix(M.getHeight()+1,M.getHeight()+1+M.getWidth(),mr); combinedMatrix.setSubMatrix(0,M.getHeight()+1,M.getHeight(),getWidth(),M); - for(int i=0;i(1); + for(int i=M.getHeight()+1;i(1); // Matrix M2=M; // M2.appendRow(Vector::allOnes(M2.getWidth())); // combinedMatrix=combineLeftRight(M2.identity(M.getHeight()+1),M2,mr); @@ -348,7 +348,7 @@ template class Tableau{ } assert(inBasis.size()==getWidth()); for(int i=0;i(1); computeRowBounds(); } Tableau(Tableau const &a, MR *mr=get_default_resource()):