File: int128.patch

package info (click to toggle)
gfan 0.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 12,680 kB
  • sloc: cpp: 63,081; makefile: 632
file content (225 lines) | stat: -rw-r--r-- 8,013 bytes parent folder | download
1
2
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()):