1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.rng.simple.internal;
19
20 import java.nio.ByteBuffer;
21 import java.nio.ByteOrder;
22 import java.util.Arrays;
23 import java.util.concurrent.ThreadLocalRandom;
24 import java.util.stream.IntStream;
25 import java.util.stream.LongStream;
26 import org.apache.commons.rng.core.source64.SplitMix64;
27 import org.apache.commons.rng.core.util.NumberFactory;
28 import org.junit.jupiter.api.Assertions;
29 import org.junit.jupiter.api.RepeatedTest;
30 import org.junit.jupiter.api.Test;
31 import org.junit.jupiter.params.ParameterizedTest;
32 import org.junit.jupiter.params.provider.MethodSource;
33 import org.junit.jupiter.params.provider.ValueSource;
34
35
36
37
38 class ConversionsTest {
39
40
41
42
43
44
45
46 private static final long GOLDEN_RATIO = 0x9e3779b97f4a7c15L;
47
48
49
50
51
52
53 static IntStream getByteLengths() {
54 return IntStream.rangeClosed(0, Long.BYTES * 2);
55 }
56
57
58
59
60
61
62 static IntStream getIntLengths() {
63 return IntStream.rangeClosed(0, (Long.BYTES / Integer.BYTES) * 2);
64 }
65
66
67
68
69
70
71 static IntStream getLongLengths() {
72 return IntStream.rangeClosed(0, 2);
73 }
74
75 @ParameterizedTest
76 @ValueSource(ints = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, Integer.MAX_VALUE})
77 void testIntSizeFromByteSize(int size) {
78 Assertions.assertEquals((int) Math.ceil((double) size / Integer.BYTES), Conversions.intSizeFromByteSize(size));
79 }
80
81 @ParameterizedTest
82 @ValueSource(ints = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, Integer.MAX_VALUE})
83 void testLongSizeFromByteSize(int size) {
84 Assertions.assertEquals((int) Math.ceil((double) size / Long.BYTES), Conversions.longSizeFromByteSize(size));
85 }
86
87 @ParameterizedTest
88 @ValueSource(ints = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, Integer.MAX_VALUE})
89 void testIntSizeFromLongSize(int size) {
90 Assertions.assertEquals((int) Math.min(size * 2L, Integer.MAX_VALUE), Conversions.intSizeFromLongSize(size));
91 }
92
93 @ParameterizedTest
94 @ValueSource(ints = {0, 1, 2, 3, 4, 5, Integer.MAX_VALUE})
95 void testLongSizeFromIntSize(int size) {
96 Assertions.assertEquals((int) Math.ceil((double) size / 2), Conversions.longSizeFromIntSize(size));
97 }
98
99 @RepeatedTest(value = 5)
100 void testInt2Long() {
101 final int v = ThreadLocalRandom.current().nextInt();
102 Assertions.assertEquals(new SplitMix64(v).nextLong(), Conversions.int2Long(v));
103 }
104
105 @RepeatedTest(value = 5)
106 void testInt2IntArray() {
107 final int v = ThreadLocalRandom.current().nextInt();
108 getIntLengths().forEach(len -> {
109 Assertions.assertArrayEquals(Conversions.long2IntArray(v, len),
110 Conversions.int2IntArray(v, len));
111 });
112 }
113
114 @RepeatedTest(value = 5)
115 void testInt2LongArray() {
116 final int v = ThreadLocalRandom.current().nextInt();
117 getIntLengths().forEach(len -> {
118 final long[] a = Conversions.int2LongArray(v, len);
119 Assertions.assertArrayEquals(Conversions.long2LongArray(v, len), a);
120 if (len != 0) {
121
122
123 Assertions.assertEquals(Conversions.int2Long(v), a[0]);
124 }
125 });
126 }
127
128 @RepeatedTest(value = 5)
129 void testLong2Int() {
130 final long v = ThreadLocalRandom.current().nextLong();
131 Assertions.assertEquals(NumberFactory.makeInt(v), Conversions.long2Int(v));
132 }
133
134 @RepeatedTest(value = 5)
135 void testLong2IntArray() {
136
137 long seed;
138 do {
139 seed = ThreadLocalRandom.current().nextLong();
140 } while (seed == -GOLDEN_RATIO);
141 final long v = seed;
142 getIntLengths().forEach(len -> {
143 final int longs = Conversions.longSizeFromIntSize(len);
144
145 final ByteBuffer bb = ByteBuffer.allocate(longs * Long.BYTES).order(ByteOrder.LITTLE_ENDIAN);
146 LongStream.generate(new SplitMix64(v)::nextLong).limit(longs).forEach(bb::putLong);
147 bb.clear();
148 final int[] expected = new int[len];
149 for (int i = 0; i < len; i++) {
150 expected[i] = bb.getInt();
151 }
152 Assertions.assertArrayEquals(expected,
153 Conversions.long2IntArray(v, len));
154
155
156
157
158 });
159 }
160
161
162
163
164
165
166
167
168 @Test
169 void testLong2IntArrayLength2NotAllZero() {
170
171
172 final long seed = -GOLDEN_RATIO;
173 Assertions.assertEquals(0, new SplitMix64(seed).nextLong());
174
175
176
177
178 Assertions.assertNotEquals(0, new SplitMix64((int) seed).nextLong());
179
180
181 final int[] actual = Conversions.long2IntArray(seed, 2);
182 Assertions.assertFalse(Arrays.equals(new int[2], actual));
183
184
185
186 Assertions.assertArrayEquals(
187 Arrays.copyOf(Conversions.long2IntArray(seed - GOLDEN_RATIO, 2), 4),
188 Conversions.long2IntArray(seed - GOLDEN_RATIO, 4));
189 }
190
191 @RepeatedTest(value = 5)
192 void testLong2LongArray() {
193 final long v = ThreadLocalRandom.current().nextLong();
194 getIntLengths().forEach(len -> {
195 Assertions.assertArrayEquals(LongStream.generate(new SplitMix64(v)::nextLong).limit(len).toArray(),
196 Conversions.long2LongArray(v, len));
197 });
198 }
199
200 @ParameterizedTest
201 @MethodSource(value = {"getIntLengths"})
202 void testIntArray2Int(int ints) {
203 final int[] seed = ThreadLocalRandom.current().ints(ints).toArray();
204
205 int expected = 0;
206 for (final int i : seed) {
207 expected ^= i;
208 }
209 Assertions.assertEquals(expected, Conversions.intArray2Int(seed));
210 }
211
212 @ParameterizedTest
213 @MethodSource(value = {"getIntLengths"})
214 void testIntArray2Long(int ints) {
215 final int[] seed = ThreadLocalRandom.current().ints(ints).toArray();
216
217
218
219 final int outLength = Conversions.longSizeFromIntSize(ints);
220 final int[] filledSeed = Arrays.copyOf(seed, outLength * 2);
221 final ByteBuffer bb = ByteBuffer.allocate(filledSeed.length * Integer.BYTES)
222 .order(ByteOrder.LITTLE_ENDIAN);
223 Arrays.stream(filledSeed).forEach(bb::putInt);
224
225 long expected = 0;
226 bb.flip();
227 for (int i = outLength; i-- != 0;) {
228 final long l = bb.getLong();
229 expected ^= l;
230 }
231
232 Assertions.assertEquals(expected, Conversions.intArray2Long(seed));
233 }
234
235 @ParameterizedTest
236 @MethodSource(value = {"getIntLengths"})
237 void testIntArray2LongComposed(int ints) {
238 final int[] seed = ThreadLocalRandom.current().ints(ints).toArray();
239 final long expected = new LongArray2Long().convert(new IntArray2LongArray().convert(seed));
240 Assertions.assertEquals(expected, Conversions.intArray2Long(seed));
241 }
242
243 @ParameterizedTest
244 @MethodSource(value = {"getIntLengths"})
245 void testIntArray2LongArray(int ints) {
246 final int[] seed = ThreadLocalRandom.current().ints(ints).toArray();
247
248
249 final int outLength = Conversions.longSizeFromIntSize(ints);
250 final ByteBuffer bb = ByteBuffer.allocate(outLength * Long.BYTES)
251 .order(ByteOrder.LITTLE_ENDIAN);
252 Arrays.stream(seed).forEach(bb::putInt);
253 bb.clear();
254 final long[] expected = new long[outLength];
255 for (int i = 0; i < outLength; i++) {
256 expected[i] = bb.getLong();
257 }
258
259 Assertions.assertArrayEquals(expected, Conversions.intArray2LongArray(seed, outLength));
260
261 Assertions.assertArrayEquals(Arrays.copyOf(expected, outLength * 2),
262 Conversions.intArray2LongArray(seed, outLength * 2));
263
264 for (int i = 0; i < outLength; i++) {
265 Assertions.assertArrayEquals(Arrays.copyOf(expected, i), Conversions.intArray2LongArray(seed, i));
266 }
267 }
268
269 @ParameterizedTest
270 @MethodSource(value = {"getLongLengths"})
271 void testLongArray2Int(long longs) {
272 final long[] seed = ThreadLocalRandom.current().longs(longs).toArray();
273
274 long expected = 0;
275 for (final long i : seed) {
276 expected ^= i;
277 }
278 Assertions.assertEquals((int) (expected ^ expected >>> 32), Conversions.longArray2Int(seed));
279 }
280
281 @ParameterizedTest
282 @MethodSource(value = {"getLongLengths"})
283 void testLongArray2Long(long longs) {
284 final long[] seed = ThreadLocalRandom.current().longs(longs).toArray();
285
286 long expected = 0;
287 for (final long i : seed) {
288 expected ^= i;
289 }
290 Assertions.assertEquals(expected, Conversions.longArray2Long(seed));
291 }
292
293 @ParameterizedTest
294 @MethodSource(value = {"getLongLengths"})
295 void testLongArray2IntArray(int longs) {
296 final long[] seed = ThreadLocalRandom.current().longs(longs).toArray();
297
298
299 final int outLength = Conversions.intSizeFromLongSize(longs);
300 final ByteBuffer bb = ByteBuffer.allocate(longs * Long.BYTES)
301 .order(ByteOrder.LITTLE_ENDIAN);
302 Arrays.stream(seed).forEach(bb::putLong);
303 bb.clear();
304 final int[] expected = new int[outLength];
305 for (int i = 0; i < outLength; i++) {
306 expected[i] = bb.getInt();
307 }
308
309 Assertions.assertArrayEquals(expected, Conversions.longArray2IntArray(seed, outLength));
310
311 Assertions.assertArrayEquals(Arrays.copyOf(expected, outLength * 2),
312 Conversions.longArray2IntArray(seed, outLength * 2));
313
314 for (int i = 0; i < outLength; i++) {
315 Assertions.assertArrayEquals(Arrays.copyOf(expected, i), Conversions.longArray2IntArray(seed, i));
316 }
317 }
318
319 @ParameterizedTest
320 @MethodSource(value = {"getByteLengths"})
321 void testByteArray2Int(int bytes) {
322 final byte[] seed = new byte[bytes];
323 ThreadLocalRandom.current().nextBytes(seed);
324
325
326
327 final int outLength = Conversions.intSizeFromByteSize(bytes);
328 final byte[] filledSeed = Arrays.copyOf(seed, outLength * Integer.BYTES);
329 final ByteBuffer bb = ByteBuffer.wrap(filledSeed)
330 .order(ByteOrder.LITTLE_ENDIAN);
331
332 int expected = 0;
333 for (int i = outLength; i-- != 0;) {
334 final long l = bb.getInt();
335 expected ^= l;
336 }
337
338 Assertions.assertEquals(expected, Conversions.byteArray2Int(seed));
339 }
340
341 @ParameterizedTest
342 @MethodSource(value = {"getByteLengths"})
343 void testByteArray2IntComposed(int bytes) {
344 final byte[] seed = new byte[bytes];
345 ThreadLocalRandom.current().nextBytes(seed);
346 final int expected = new IntArray2Int().convert(new ByteArray2IntArray().convert(seed));
347 Assertions.assertEquals(expected, Conversions.byteArray2Int(seed));
348 }
349
350 @ParameterizedTest
351 @MethodSource(value = {"getByteLengths"})
352 void testByteArray2IntArray(int bytes) {
353 final byte[] seed = new byte[bytes];
354 ThreadLocalRandom.current().nextBytes(seed);
355
356
357 final int outLength = Conversions.intSizeFromByteSize(bytes);
358 final byte[] filledSeed = Arrays.copyOf(seed, outLength * Integer.BYTES);
359 final ByteBuffer bb = ByteBuffer.wrap(filledSeed)
360 .order(ByteOrder.LITTLE_ENDIAN);
361 final int[] expected = new int[outLength];
362 for (int i = 0; i < outLength; i++) {
363 expected[i] = bb.getInt();
364 }
365
366 Assertions.assertArrayEquals(expected, Conversions.byteArray2IntArray(seed, outLength));
367
368 Assertions.assertArrayEquals(Arrays.copyOf(expected, outLength * 2),
369 Conversions.byteArray2IntArray(seed, outLength * 2));
370
371 for (int i = 0; i < outLength; i++) {
372 Assertions.assertArrayEquals(Arrays.copyOf(expected, i), Conversions.byteArray2IntArray(seed, i));
373 }
374 }
375
376 @ParameterizedTest
377 @MethodSource(value = {"getByteLengths"})
378 void testByteArray2Long(int bytes) {
379 final byte[] seed = new byte[bytes];
380 ThreadLocalRandom.current().nextBytes(seed);
381
382
383
384 final int outLength = Conversions.longSizeFromByteSize(bytes);
385 final byte[] filledSeed = Arrays.copyOf(seed, outLength * Long.BYTES);
386 final ByteBuffer bb = ByteBuffer.wrap(filledSeed)
387 .order(ByteOrder.LITTLE_ENDIAN);
388
389 long expected = 0;
390 for (int i = outLength; i-- != 0;) {
391 final long l = bb.getLong();
392 expected ^= l;
393 }
394
395 Assertions.assertEquals(expected, Conversions.byteArray2Long(seed));
396 }
397
398 @ParameterizedTest
399 @MethodSource(value = {"getByteLengths"})
400 void testByteArray2LongComposed(int bytes) {
401 final byte[] seed = new byte[bytes];
402 ThreadLocalRandom.current().nextBytes(seed);
403 final long expected = new LongArray2Long().convert(new ByteArray2LongArray().convert(seed));
404 Assertions.assertEquals(expected, Conversions.byteArray2Long(seed));
405 }
406
407 @ParameterizedTest
408 @MethodSource(value = {"getByteLengths"})
409 void testByteArray2LongArray(int bytes) {
410 final byte[] seed = new byte[bytes];
411 ThreadLocalRandom.current().nextBytes(seed);
412
413
414 final int outLength = Conversions.longSizeFromByteSize(bytes);
415 final byte[] filledSeed = Arrays.copyOf(seed, outLength * Long.BYTES);
416 final ByteBuffer bb = ByteBuffer.wrap(filledSeed)
417 .order(ByteOrder.LITTLE_ENDIAN);
418 final long[] expected = new long[outLength];
419 for (int i = 0; i < outLength; i++) {
420 expected[i] = bb.getLong();
421 }
422
423 Assertions.assertArrayEquals(expected, Conversions.byteArray2LongArray(seed, outLength));
424
425 Assertions.assertArrayEquals(Arrays.copyOf(expected, outLength * 2),
426 Conversions.byteArray2LongArray(seed, outLength * 2));
427
428 for (int i = 0; i < outLength; i++) {
429 Assertions.assertArrayEquals(Arrays.copyOf(expected, i), Conversions.byteArray2LongArray(seed, i));
430 }
431 }
432 }