| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 
 | Description: Use 128-bit integers from Abseil when not available natively.
Author: Doug Torrance <dtorrance@debian.org>
Last-Update: 2024-10-24
--- a/src/gfanlib_circuittableint.h
+++ b/src/gfanlib_circuittableint.h
@@ -17,6 +17,12 @@
 #include <iomanip>
 #include "gfanlib_frequencytable.h"
 
+#ifndef __SIZEOF_INT128__
+#include <absl/numeric/int128.h>
+typedef absl::int128 __int128_t;
+typedef absl::uint128 __uint128_t;
+#endif
+
 namespace gfan{
 
 
@@ -25,7 +31,8 @@
   template<typename> struct MyMakeUnsigned;
   template <> struct MyMakeUnsigned<int>{typedef unsigned int type;};
   template <> struct MyMakeUnsigned<long int>{typedef unsigned long int type;};
-  template <> struct MyMakeUnsigned<__int128>{typedef unsigned __int128 type;};
+  template <> struct MyMakeUnsigned<long long int>{typedef unsigned long long int type;};
+  template <> struct MyMakeUnsigned<__int128_t>{typedef __uint128_t type;};
 
   class MVMachineIntegerOverflow: public std::exception
 {
@@ -92,6 +99,15 @@
 	return s.str();
 }
 
+#ifndef __SIZEOF_INT128__
+static std::string toStr(long int b)
+{
+	std::stringstream s;
+	s<<b;
+	return s.str();
+}
+#endif
+
 class my256s{
 public:
 	__int128_t lo,hi;
@@ -106,6 +122,23 @@
 	{
 		if(v<0)hi=-1;
 	}
+#ifndef __SIZEOF_INT128__
+	my256s(int lo_,__int128_t hi_):
+		lo(static_cast<__int128_t>(lo_)),
+		hi(hi_)
+	{
+	}
+	my256s(__uint128_t lo_,__int128_t hi_):
+		lo(static_cast<__int128_t>(lo_)),
+		hi(hi_)
+	{
+	}
+	my256s(__int128_t lo_,__uint128_t hi_):
+		lo(lo_),
+		hi(static_cast<__int128_t>(hi_))
+	{
+	}
+#endif
 	my256s operator+(my256s b)
 	{
 		__uint128_t newLo=lo+b.lo;
@@ -165,7 +198,7 @@
 		my256s temp(~lo,~hi);
 		return temp+my256s(1,0);
 	}
-	explicit operator __int128()const
+	explicit operator __int128_t()const
 	{
 		return lo;
 	}
@@ -213,12 +246,23 @@
 {
 	return ((__int128_t)a)*((__int128_t)b);
 }
+static long long int extMul(long long int a, long long int b)
+{
+	return a * b;
+}
 
 static __uint128_t unsignedProd64(uint64_t x,uint64_t y)
 {
 	return __uint128_t(x)*__uint128_t(y);
 }
 
+#ifndef __SIZEOF_INT128__
+static __uint128_t unsignedProd64(__uint128_t x,__uint128_t y)
+{
+	return x * y;
+}
+#endif
+
 static my256u unsignedProd128(__uint128_t x,__uint128_t y)
 {
 	my256s a(unsignedProd64(x,y),0);
@@ -302,7 +346,7 @@
 	friend CircuitTableIntPOD operator*(CircuitTableIntPOD const &a, CircuitTableIntPOD const &b){CircuitTableIntPOD ret;ret.v=a.v*b.v;return ret;}
 	friend CircuitTableIntPOD operator/(CircuitTableIntPOD const &a, CircuitTableIntPOD const &b){CircuitTableIntPOD ret;ret.v=a.v/b.v;return ret;}//This is used very few times. Should we require this be an exact division?
  public:
-	static const word halfBound{(word{1}<<(std::numeric_limits<word>::digits/2-2))-1};
+	static constexpr word halfBound{(word{1}<<(std::numeric_limits<word>::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<halfBound;}// Is it better to allow only non-negative numbers?
 	static bool isSuitableSummationNumber(int numberOfSummands){return numberOfSummands<halfBound;}
@@ -352,7 +396,7 @@
 	//	return std::to_string((int64_t)v);/*cast seems to be needed (128 bit will not work)*/
 		return toStr(v);
 	}
-	int64_t toInt64()const{return v;}//WHAT SHOULD HAPPEN TO THIS FUNCTION?
+	int64_t toInt64()const{return static_cast<int64_t>(v);}//WHAT SHOULD HAPPEN TO THIS FUNCTION?
   friend std::ostream &operator<<(std::ostream &f, CircuitTableIntPOD const &a){f<</*(int)*/a.toString();return f;}
 	Double extend()const{Double ret;ret.v=v;return ret;}
 	CircuitTableIntPOD &maddWithOverflowChecking(CircuitTableIntPOD const &a, CircuitTableIntPOD const&b){Double t=this->extend();t+=extendedMultiplication(a,b);*this=t.castToSingle();return *this;}
@@ -546,8 +590,8 @@
 			  int D=std::numeric_limits<word>::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<longword>(0);
+			  longword max64=static_cast<longword>(0);
 			  for(int i=0;i<c;i++)
 			  {
 				  // In the unlikely event that all the numbers to be multiplied are -2^31, the following code will overflow. Therefore the overflow flag was set as above.
@@ -569,15 +613,14 @@
 	static CircuitTableIntPOD quickScaleNoShiftBounded(CircuitTableIntPOD * __restrict__ aa, CircuitTableIntPOD s, CircuitTableIntPOD::Divisor denominatorDivisor,int c, CircuitTableIntPOD boundA)
 	{
 //		assert(!boundA.isPositive());
-		if(0)
-		{
+#if 0
 			static FrequencyTable A("Multiplier");
 			A.record(s.toInt64()&255);
 			static FrequencyTable B("Divisor");
 			B.record(denominatorDivisor.v&255);
 			static FrequencyTable C("AreEqual");
 			C.record(s.toInt64()==denominatorDivisor.v);
-		}
+#endif
 		CircuitTableIntPOD max{};assert(max.v==0);
 	    CircuitTableIntPOD min{};assert(min.v==0);
 	    CircuitTableIntPOD ret{};assert(ret.v==0);
@@ -663,8 +706,8 @@
 			  int D=std::numeric_limits<word>::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<longword>(0);
+			  longword max64=static_cast<longword>(0);
 			  for(int i=0;i<c;i++)
 			  {
 				  longword/*int64_t*/ temp=(extMul(s.v,aa[i].v))/denominatorDivisor.v;
@@ -737,7 +780,7 @@
 {
 	if(v>=0x7fffffffffffffff || -v>=0x7fffffffffffffff) throw MVMachineIntegerOverflow;
 	CircuitTableIntPOD ret;
-	ret.v=v;
+	ret.v=static_cast<int64_t>(v);
 	return ret;
 }
 
@@ -746,7 +789,7 @@
   // DANGER !!!
   //if(v>=0x7fffffffffffffffffffffffffffffff || -v>=0x7fffffffffffffffffffffffffffffff) throw MVMachineIntegerOverflow;
 	CircuitTableIntPOD ret;
-	ret.v=__int128(v);
+	ret.v=__int128_t(v);
 	return ret;
 }
 
@@ -784,6 +827,7 @@
 	CircuitTableInt128()noexcept{v=0;}
 	CircuitTableInt128(CircuitTableInt128POD const &m){v=m.v;}
 	CircuitTableInt128(__int128_t val){v=val;}
+	CircuitTableInt128(int val){v=val;}
 	CircuitTableInt128(std::string const&s){
 	  int64_t proxy;
 	  std::istringstream a(s); a>>proxy;
--- a/src/app_test.cpp
+++ b/src/app_test.cpp
@@ -764,10 +764,10 @@
 
 
 		{
-			  __int128 t=0;
-			  __int128 A=2;
-			  __int128 s=-4;
-			  __int128 B=1;
+			  __int128_t t=0;
+			  __int128_t A=2;
+			  __int128_t s=-4;
+			  __int128_t B=1;
 			  B=(B<<127)+3;
 			  std::cerr<<"---B\n";
 			  std::cerr<<toStr(t)<<"\n";
--- a/src/gfanlib_tableau.h
+++ b/src/gfanlib_tableau.h
@@ -334,8 +334,8 @@
 			{
 				combinedMatrix=Matrix<mvtyp>(M.getHeight()+1,M.getHeight()+1+M.getWidth(),mr);
 				combinedMatrix.setSubMatrix(0,M.getHeight()+1,M.getHeight(),getWidth(),M);
-				for(int i=0;i<M.getHeight()+1;i++)combinedMatrix[i][i]=1;
-				for(int i=M.getHeight()+1;i<getWidth();i++)combinedMatrix[M.getHeight()][i]=1;
+				for(int i=0;i<M.getHeight()+1;i++)combinedMatrix[i][i]=static_cast<mvtyp>(1);
+				for(int i=M.getHeight()+1;i<getWidth();i++)combinedMatrix[M.getHeight()][i]=static_cast<mvtyp>(1);
 //				Matrix<mvtyp> M2=M;
 //				M2.appendRow(Vector<mvtyp>::allOnes(M2.getWidth()));
 //				combinedMatrix=combineLeftRight(M2.identity(M.getHeight()+1),M2,mr);
@@ -347,7 +347,7 @@
 			}
 			assert(inBasis.size()==getWidth());
 			for(int i=0;i<M.getHeight()+appendAllOnes;i++){basisIndices[i]=i;inBasis[i]=true;}
-			determinantOfBasis=1;
+			determinantOfBasis=static_cast<mvtyp>(1);
 			computeRowBounds();
 		}
 		Tableau(Tableau<mvtyp> const &a, MR *mr=get_default_resource()):
 |