1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.statistics.examples.jmh.descriptive;
18
19 import java.math.BigInteger;
20 import java.nio.ByteBuffer;
21 import org.apache.commons.numbers.core.DD;
22
23
24
25
26
27
28
29
30
31
32
33 final class UInt192 {
34
35 private static final long MASK32 = 0xffff_ffffL;
36
37
38
39
40 private int f;
41
42 private int e;
43
44 private int d;
45
46 private int c;
47
48 private long ab;
49
50
51
52
53 private UInt192() {
54
55 }
56
57
58
59
60
61
62
63
64
65 UInt192(long hi, long mid, long lo) {
66 this.f = (int) lo;
67 this.e = (int) (lo >>> Integer.SIZE);
68 this.d = (int) mid;
69 this.c = (int) (mid >>> Integer.SIZE);
70 this.ab = hi;
71 }
72
73
74
75
76
77
78
79
80
81
82 private UInt192(long ab, int c, int d, int e, int f) {
83 this.ab = ab;
84 this.c = c;
85 this.d = d;
86 this.e = e;
87 this.f = f;
88 }
89
90
91
92
93
94
95 static UInt192 create() {
96 return new UInt192();
97 }
98
99
100
101
102
103
104 void addSquare(long x) {
105 final long lo = x * x;
106 final long hi = IntMath.squareHigh(x);
107
108
109 long s = (lo & MASK32) + (f & MASK32);
110 f = (int) s;
111 s = (s >>> Integer.SIZE) + (lo >>> Integer.SIZE) + (e & MASK32);
112 e = (int) s;
113 s = (s >>> Integer.SIZE) + (hi & MASK32) + (d & MASK32);
114 d = (int) s;
115 s = (s >>> Integer.SIZE) + (hi >>> Integer.SIZE) + (c & MASK32);
116 c = (int) s;
117 ab += s >>> Integer.SIZE;
118 }
119
120
121
122
123
124
125
126
127 void addSquare2(long x) {
128 final long lo = x * x;
129 final long hi = Math.multiplyHigh(x, x);
130
131
132 long s = (lo & MASK32) + (f & MASK32);
133 f = (int) s;
134 s = (s >>> Integer.SIZE) + (lo >>> Integer.SIZE) + (e & MASK32);
135 e = (int) s;
136 s = (s >>> Integer.SIZE) + (hi & MASK32) + (d & MASK32);
137 d = (int) s;
138 s = (s >>> Integer.SIZE) + (hi >>> Integer.SIZE) + (c & MASK32);
139 c = (int) s;
140 ab += s >>> Integer.SIZE;
141 }
142
143
144
145
146
147
148 void add(UInt192 x) {
149
150 final int ff = x.f;
151 final int ee = x.e;
152 final int dd = x.d;
153 final int cc = x.c;
154 final long aabb = x.ab;
155
156 long s = (ff & MASK32) + (f & MASK32);
157 f = (int) s;
158 s = (s >>> Integer.SIZE) + (ee & MASK32) + (e & MASK32);
159 e = (int) s;
160 s = (s >>> Integer.SIZE) + (dd & MASK32) + (d & MASK32);
161 d = (int) s;
162 s = (s >>> Integer.SIZE) + (cc & MASK32) + (c & MASK32);
163 c = (int) s;
164 ab += (s >>> Integer.SIZE) + aabb;
165 }
166
167
168
169
170
171
172
173
174
175 UInt192 unsignedMultiply(int x) {
176 final long xx = x & MASK32;
177
178 long product = xx * (f & MASK32);
179 final int ff = (int) product;
180 product = (product >>> Integer.SIZE) + xx * (e & MASK32);
181 final int ee = (int) product;
182 product = (product >>> Integer.SIZE) + xx * (d & MASK32);
183 final int dd = (int) product;
184 product = (product >>> Integer.SIZE) + xx * (c & MASK32);
185 final int cc = (int) product;
186
187 final long aabb = (product >>> Integer.SIZE) + xx * ab;
188 return new UInt192(aabb, cc, dd, ee, ff);
189 }
190
191
192
193
194
195
196
197
198 UInt192 subtract(UInt128 x) {
199
200
201 long diff = (f & MASK32) - (x.lo32() & MASK32);
202 final int ff = (int) diff;
203 diff = (diff >> Integer.SIZE) + (e & MASK32) - (x.mid32() & MASK32);
204 final int ee = (int) diff;
205 diff = (diff >> Integer.SIZE) + (d & MASK32) - (x.hi64() & MASK32);
206 final int dd = (int) diff;
207 diff = (diff >> Integer.SIZE) + (c & MASK32) - (x.hi64() >>> Integer.SIZE);
208 final int cc = (int) diff;
209
210
211 final long aabb = (diff >> Integer.SIZE) + ab;
212 return new UInt192(aabb, cc, dd, ee, ff);
213 }
214
215
216
217
218
219
220 BigInteger toBigInteger() {
221 final ByteBuffer bb = ByteBuffer.allocate(Integer.BYTES * 6)
222 .putLong(ab)
223 .putInt(c)
224 .putInt(d)
225 .putInt(e)
226 .putInt(f);
227
228 return new BigInteger(1, bb.array());
229 }
230
231
232
233
234
235
236 double toDouble() {
237 final long h = hi64();
238 final long m = mid64();
239 final long l = lo64();
240 if (h == 0) {
241 return IntMath.uin128ToDouble(m, l);
242 }
243
244
245 return IntMath.uin128ToDouble(h, m | ((l != 0) ? 1 : 0)) * 0x1.0p64;
246 }
247
248
249
250
251
252
253 DD toDD() {
254
255 return DD.ofSum(f & MASK32, (e & MASK32) * 0x1.0p32)
256 .add((d & MASK32) * 0x1.0p64)
257 .add((c & MASK32) * 0x1.0p96)
258 .add((ab & MASK32) * 0x1.0p128)
259 .add((ab >>> Integer.SIZE) * 0x1.0p160);
260 }
261
262
263
264
265
266
267 long lo64() {
268 return (f & MASK32) | ((e & MASK32) << Integer.SIZE);
269 }
270
271
272
273
274
275
276 long mid64() {
277 return (d & MASK32) | ((c & MASK32) << Integer.SIZE);
278 }
279
280
281
282
283
284
285 long hi64() {
286 return ab;
287 }
288
289
290
291
292
293
294 int hi32() {
295 return (int) (ab >>> Integer.SIZE);
296 }
297 }