1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.util;
23
24 import org.hipparchus.exception.MathIllegalArgumentException;
25 import org.hipparchus.exception.MathRuntimeException;
26 import org.hipparchus.random.RandomDataGenerator;
27 import org.junit.jupiter.api.Test;
28 import org.junit.jupiter.api.Timeout;
29
30 import java.math.BigInteger;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.concurrent.TimeUnit;
34
35 import static org.junit.jupiter.api.Assertions.assertEquals;
36 import static org.junit.jupiter.api.Assertions.assertThrows;
37 import static org.junit.jupiter.api.Assertions.assertTrue;
38 import static org.junit.jupiter.api.Assertions.fail;
39
40
41
42
43 class ArithmeticUtilsTest {
44
45 @Test
46 void testAddAndCheck() {
47 int big = Integer.MAX_VALUE;
48 int bigNeg = Integer.MIN_VALUE;
49 assertEquals(big, ArithmeticUtils.addAndCheck(big, 0));
50 try {
51 ArithmeticUtils.addAndCheck(big, 1);
52 fail("Expecting MathRuntimeException");
53 } catch (MathRuntimeException ex) {
54 }
55 try {
56 ArithmeticUtils.addAndCheck(bigNeg, -1);
57 fail("Expecting MathRuntimeException");
58 } catch (MathRuntimeException ex) {
59 }
60 }
61
62 @Test
63 void testAddAndCheckLong() {
64 long max = Long.MAX_VALUE;
65 long min = Long.MIN_VALUE;
66 assertEquals(max, ArithmeticUtils.addAndCheck(max, 0L));
67 assertEquals(min, ArithmeticUtils.addAndCheck(min, 0L));
68 assertEquals(max, ArithmeticUtils.addAndCheck(0L, max));
69 assertEquals(min, ArithmeticUtils.addAndCheck(0L, min));
70 assertEquals(1, ArithmeticUtils.addAndCheck(-1L, 2L));
71 assertEquals(1, ArithmeticUtils.addAndCheck(2L, -1L));
72 assertEquals(-3, ArithmeticUtils.addAndCheck(-2L, -1L));
73 assertEquals(min, ArithmeticUtils.addAndCheck(min + 1, -1L));
74 assertEquals(-1, ArithmeticUtils.addAndCheck(min, max));
75 testAddAndCheckLongFailure(max, 1L);
76 testAddAndCheckLongFailure(min, -1L);
77 testAddAndCheckLongFailure(1L, max);
78 testAddAndCheckLongFailure(-1L, min);
79 testAddAndCheckLongFailure(max, max);
80 testAddAndCheckLongFailure(min, min);
81 }
82
83 @Test
84 void testGcd() {
85 int a = 30;
86 int b = 50;
87 int c = 77;
88
89 assertEquals(0, ArithmeticUtils.gcd(0, 0));
90
91 assertEquals(b, ArithmeticUtils.gcd(0, b));
92 assertEquals(a, ArithmeticUtils.gcd(a, 0));
93 assertEquals(b, ArithmeticUtils.gcd(0, -b));
94 assertEquals(a, ArithmeticUtils.gcd(-a, 0));
95
96 assertEquals(10, ArithmeticUtils.gcd(a, b));
97 assertEquals(10, ArithmeticUtils.gcd(-a, b));
98 assertEquals(10, ArithmeticUtils.gcd(a, -b));
99 assertEquals(10, ArithmeticUtils.gcd(-a, -b));
100
101 assertEquals(1, ArithmeticUtils.gcd(a, c));
102 assertEquals(1, ArithmeticUtils.gcd(-a, c));
103 assertEquals(1, ArithmeticUtils.gcd(a, -c));
104 assertEquals(1, ArithmeticUtils.gcd(-a, -c));
105
106 assertEquals(3 * (1<<15), ArithmeticUtils.gcd(3 * (1<<20), 9 * (1<<15)));
107
108 assertEquals(Integer.MAX_VALUE, ArithmeticUtils.gcd(Integer.MAX_VALUE, 0));
109 assertEquals(Integer.MAX_VALUE, ArithmeticUtils.gcd(-Integer.MAX_VALUE, 0));
110 assertEquals(1<<30, ArithmeticUtils.gcd(1<<30, -Integer.MIN_VALUE));
111 try {
112
113 ArithmeticUtils.gcd(Integer.MIN_VALUE, 0);
114 fail("expecting MathRuntimeException");
115 } catch (MathRuntimeException expected) {
116
117 }
118 try {
119
120 ArithmeticUtils.gcd(0, Integer.MIN_VALUE);
121 fail("expecting MathRuntimeException");
122 } catch (MathRuntimeException expected) {
123
124 }
125 try {
126
127 ArithmeticUtils.gcd(Integer.MIN_VALUE, Integer.MIN_VALUE);
128 fail("expecting MathRuntimeException");
129 } catch (MathRuntimeException expected) {
130
131 }
132 }
133
134 @Test
135 void testGcdConsistency() {
136 int[] primeList = {19, 23, 53, 67, 73, 79, 101, 103, 111, 131};
137 ArrayList<Integer> primes = new ArrayList<Integer>();
138 for (int i = 0; i < primeList.length; i++) {
139 primes.add(Integer.valueOf(primeList[i]));
140 }
141 RandomDataGenerator randomData = new RandomDataGenerator();
142 for (int i = 0; i < 20; i++) {
143 Object[] sample = randomData.nextSample(primes, 4);
144 int p1 = ((Integer) sample[0]).intValue();
145 int p2 = ((Integer) sample[1]).intValue();
146 int p3 = ((Integer) sample[2]).intValue();
147 int p4 = ((Integer) sample[3]).intValue();
148 int i1 = p1 * p2 * p3;
149 int i2 = p1 * p2 * p4;
150 int gcd = p1 * p2;
151 assertEquals(gcd, ArithmeticUtils.gcd(i1, i2));
152 long l1 = i1;
153 long l2 = i2;
154 assertEquals(gcd, ArithmeticUtils.gcd(l1, l2));
155 }
156 }
157
158 @Test
159 void testGcdLong(){
160 long a = 30;
161 long b = 50;
162 long c = 77;
163
164 assertEquals(0, ArithmeticUtils.gcd(0L, 0));
165
166 assertEquals(b, ArithmeticUtils.gcd(0, b));
167 assertEquals(a, ArithmeticUtils.gcd(a, 0));
168 assertEquals(b, ArithmeticUtils.gcd(0, -b));
169 assertEquals(a, ArithmeticUtils.gcd(-a, 0));
170
171 assertEquals(10, ArithmeticUtils.gcd(a, b));
172 assertEquals(10, ArithmeticUtils.gcd(-a, b));
173 assertEquals(10, ArithmeticUtils.gcd(a, -b));
174 assertEquals(10, ArithmeticUtils.gcd(-a, -b));
175
176 assertEquals(1, ArithmeticUtils.gcd(a, c));
177 assertEquals(1, ArithmeticUtils.gcd(-a, c));
178 assertEquals(1, ArithmeticUtils.gcd(a, -c));
179 assertEquals(1, ArithmeticUtils.gcd(-a, -c));
180
181 assertEquals(3L * (1L<<45), ArithmeticUtils.gcd(3L * (1L<<50), 9L * (1L<<45)));
182
183 assertEquals(1L<<45, ArithmeticUtils.gcd(1L<<45, Long.MIN_VALUE));
184
185 assertEquals(Long.MAX_VALUE, ArithmeticUtils.gcd(Long.MAX_VALUE, 0L));
186 assertEquals(Long.MAX_VALUE, ArithmeticUtils.gcd(-Long.MAX_VALUE, 0L));
187 assertEquals(1, ArithmeticUtils.gcd(60247241209L, 153092023L));
188 try {
189
190 ArithmeticUtils.gcd(Long.MIN_VALUE, 0);
191 fail("expecting MathRuntimeException");
192 } catch (MathRuntimeException expected) {
193
194 }
195 try {
196
197 ArithmeticUtils.gcd(0, Long.MIN_VALUE);
198 fail("expecting MathRuntimeException");
199 } catch (MathRuntimeException expected) {
200
201 }
202 try {
203
204 ArithmeticUtils.gcd(Long.MIN_VALUE, Long.MIN_VALUE);
205 fail("expecting MathRuntimeException");
206 } catch (MathRuntimeException expected) {
207
208 }
209 }
210
211
212 @Test
213 void testLcm() {
214 int a = 30;
215 int b = 50;
216 int c = 77;
217
218 assertEquals(0, ArithmeticUtils.lcm(0, b));
219 assertEquals(0, ArithmeticUtils.lcm(a, 0));
220 assertEquals(b, ArithmeticUtils.lcm(1, b));
221 assertEquals(a, ArithmeticUtils.lcm(a, 1));
222 assertEquals(150, ArithmeticUtils.lcm(a, b));
223 assertEquals(150, ArithmeticUtils.lcm(-a, b));
224 assertEquals(150, ArithmeticUtils.lcm(a, -b));
225 assertEquals(150, ArithmeticUtils.lcm(-a, -b));
226 assertEquals(2310, ArithmeticUtils.lcm(a, c));
227
228
229
230 assertEquals((1<<20)*15, ArithmeticUtils.lcm((1<<20)*3, (1<<20)*5));
231
232
233 assertEquals(0, ArithmeticUtils.lcm(0, 0));
234
235 try {
236
237 ArithmeticUtils.lcm(Integer.MIN_VALUE, 1);
238 fail("Expecting MathRuntimeException");
239 } catch (MathRuntimeException expected) {
240
241 }
242
243 try {
244
245 ArithmeticUtils.lcm(Integer.MIN_VALUE, 1<<20);
246 fail("Expecting MathRuntimeException");
247 } catch (MathRuntimeException expected) {
248
249 }
250
251 try {
252 ArithmeticUtils.lcm(Integer.MAX_VALUE, Integer.MAX_VALUE - 1);
253 fail("Expecting MathRuntimeException");
254 } catch (MathRuntimeException expected) {
255
256 }
257 }
258
259 @Test
260 void testLcmLong() {
261 long a = 30;
262 long b = 50;
263 long c = 77;
264
265 assertEquals(0, ArithmeticUtils.lcm(0, b));
266 assertEquals(0, ArithmeticUtils.lcm(a, 0));
267 assertEquals(b, ArithmeticUtils.lcm(1, b));
268 assertEquals(a, ArithmeticUtils.lcm(a, 1));
269 assertEquals(150, ArithmeticUtils.lcm(a, b));
270 assertEquals(150, ArithmeticUtils.lcm(-a, b));
271 assertEquals(150, ArithmeticUtils.lcm(a, -b));
272 assertEquals(150, ArithmeticUtils.lcm(-a, -b));
273 assertEquals(2310, ArithmeticUtils.lcm(a, c));
274
275 assertEquals(Long.MAX_VALUE, ArithmeticUtils.lcm(60247241209L, 153092023L));
276
277
278
279 assertEquals((1L<<50)*15, ArithmeticUtils.lcm((1L<<45)*3, (1L<<50)*5));
280
281
282 assertEquals(0L, ArithmeticUtils.lcm(0L, 0L));
283
284 try {
285
286 ArithmeticUtils.lcm(Long.MIN_VALUE, 1);
287 fail("Expecting MathRuntimeException");
288 } catch (MathRuntimeException expected) {
289
290 }
291
292 try {
293
294 ArithmeticUtils.lcm(Long.MIN_VALUE, 1<<20);
295 fail("Expecting MathRuntimeException");
296 } catch (MathRuntimeException expected) {
297
298 }
299
300 assertEquals((long) Integer.MAX_VALUE * (Integer.MAX_VALUE - 1),
301 ArithmeticUtils.lcm((long)Integer.MAX_VALUE, Integer.MAX_VALUE - 1));
302 try {
303 ArithmeticUtils.lcm(Long.MAX_VALUE, Long.MAX_VALUE - 1);
304 fail("Expecting MathRuntimeException");
305 } catch (MathRuntimeException expected) {
306
307 }
308 }
309
310 @Test
311 void testMulAndCheck() {
312 int big = Integer.MAX_VALUE;
313 int bigNeg = Integer.MIN_VALUE;
314 assertEquals(big, ArithmeticUtils.mulAndCheck(big, 1));
315 try {
316 ArithmeticUtils.mulAndCheck(big, 2);
317 fail("Expecting MathRuntimeException");
318 } catch (MathRuntimeException ex) {
319 }
320 try {
321 ArithmeticUtils.mulAndCheck(bigNeg, 2);
322 fail("Expecting MathRuntimeException");
323 } catch (MathRuntimeException ex) {
324 }
325 }
326
327 @Test
328 void testMulAndCheckLong() {
329 long max = Long.MAX_VALUE;
330 long min = Long.MIN_VALUE;
331 assertEquals(max, ArithmeticUtils.mulAndCheck(max, 1L));
332 assertEquals(min, ArithmeticUtils.mulAndCheck(min, 1L));
333 assertEquals(0L, ArithmeticUtils.mulAndCheck(max, 0L));
334 assertEquals(0L, ArithmeticUtils.mulAndCheck(min, 0L));
335 assertEquals(max, ArithmeticUtils.mulAndCheck(1L, max));
336 assertEquals(min, ArithmeticUtils.mulAndCheck(1L, min));
337 assertEquals(0L, ArithmeticUtils.mulAndCheck(0L, max));
338 assertEquals(0L, ArithmeticUtils.mulAndCheck(0L, min));
339 assertEquals(1L, ArithmeticUtils.mulAndCheck(-1L, -1L));
340 assertEquals(min, ArithmeticUtils.mulAndCheck(min / 2, 2));
341 testMulAndCheckLongFailure(max, 2L);
342 testMulAndCheckLongFailure(2L, max);
343 testMulAndCheckLongFailure(min, 2L);
344 testMulAndCheckLongFailure(2L, min);
345 testMulAndCheckLongFailure(min, -1L);
346 testMulAndCheckLongFailure(-1L, min);
347 }
348
349 @Test
350 void testSubAndCheck() {
351 int big = Integer.MAX_VALUE;
352 int bigNeg = Integer.MIN_VALUE;
353 assertEquals(big, ArithmeticUtils.subAndCheck(big, 0));
354 assertEquals(bigNeg + 1, ArithmeticUtils.subAndCheck(bigNeg, -1));
355 assertEquals(-1, ArithmeticUtils.subAndCheck(bigNeg, -big));
356 try {
357 ArithmeticUtils.subAndCheck(big, -1);
358 fail("Expecting MathRuntimeException");
359 } catch (MathRuntimeException ex) {
360 }
361 try {
362 ArithmeticUtils.subAndCheck(bigNeg, 1);
363 fail("Expecting MathRuntimeException");
364 } catch (MathRuntimeException ex) {
365 }
366 }
367
368 @Test
369 void testSubAndCheckErrorMessage() {
370 int big = Integer.MAX_VALUE;
371 try {
372 ArithmeticUtils.subAndCheck(big, -1);
373 fail("Expecting MathRuntimeException");
374 } catch (MathRuntimeException ex) {
375 assertTrue(ex.getMessage().length() > 1);
376 }
377 }
378
379 @Test
380 void testSubAndCheckLong() {
381 long max = Long.MAX_VALUE;
382 long min = Long.MIN_VALUE;
383 assertEquals(max, ArithmeticUtils.subAndCheck(max, 0));
384 assertEquals(min, ArithmeticUtils.subAndCheck(min, 0));
385 assertEquals(-max, ArithmeticUtils.subAndCheck(0, max));
386 assertEquals(min + 1, ArithmeticUtils.subAndCheck(min, -1));
387
388 assertEquals(-1, ArithmeticUtils.subAndCheck(-max - 1, -max));
389 assertEquals(max, ArithmeticUtils.subAndCheck(-1, -1 - max));
390 testSubAndCheckLongFailure(0L, min);
391 testSubAndCheckLongFailure(max, -1L);
392 testSubAndCheckLongFailure(min, 1L);
393 }
394
395 @Test
396 void testPow() {
397
398 assertEquals(1801088541, ArithmeticUtils.pow(21, 7));
399 assertEquals(1, ArithmeticUtils.pow(21, 0));
400 try {
401 ArithmeticUtils.pow(21, -7);
402 fail("Expecting MathIllegalArgumentException");
403 } catch (MathIllegalArgumentException e) {
404
405 }
406
407 assertEquals(1801088541, ArithmeticUtils.pow(21, 7));
408 assertEquals(1, ArithmeticUtils.pow(21, 0));
409 try {
410 ArithmeticUtils.pow(21, -7);
411 fail("Expecting MathIllegalArgumentException");
412 } catch (MathIllegalArgumentException e) {
413
414 }
415
416 assertEquals(1801088541L, ArithmeticUtils.pow(21L, 7));
417 assertEquals(1L, ArithmeticUtils.pow(21L, 0));
418 try {
419 ArithmeticUtils.pow(21L, -7);
420 fail("Expecting MathIllegalArgumentException");
421 } catch (MathIllegalArgumentException e) {
422
423 }
424
425 BigInteger twentyOne = BigInteger.valueOf(21L);
426 assertEquals(BigInteger.valueOf(1801088541L), ArithmeticUtils.pow(twentyOne, 7));
427 assertEquals(BigInteger.ONE, ArithmeticUtils.pow(twentyOne, 0));
428 try {
429 ArithmeticUtils.pow(twentyOne, -7);
430 fail("Expecting MathIllegalArgumentException");
431 } catch (MathIllegalArgumentException e) {
432
433 }
434
435 assertEquals(BigInteger.valueOf(1801088541L), ArithmeticUtils.pow(twentyOne,
436 7L));
437 assertEquals(BigInteger.ONE, ArithmeticUtils.pow(twentyOne, 0L));
438 try {
439 ArithmeticUtils.pow(twentyOne, -7L);
440 fail("Expecting MathIllegalArgumentException");
441 } catch (MathIllegalArgumentException e) {
442
443 }
444
445 assertEquals(BigInteger.valueOf(1801088541L), ArithmeticUtils.pow(twentyOne, BigInteger.valueOf(
446 7L)));
447 assertEquals(BigInteger.ONE, ArithmeticUtils.pow(twentyOne, BigInteger.ZERO));
448 try {
449 ArithmeticUtils.pow(twentyOne, BigInteger.valueOf(-7L));
450 fail("Expecting MathIllegalArgumentException");
451 } catch (MathIllegalArgumentException e) {
452
453 }
454
455 BigInteger bigOne =
456 new BigInteger("1543786922199448028351389769265814882661837148" +
457 "4763915343722775611762713982220306372888519211" +
458 "560905579993523402015636025177602059044911261");
459 assertEquals(bigOne, ArithmeticUtils.pow(twentyOne, 103));
460 assertEquals(bigOne, ArithmeticUtils.pow(twentyOne, 103L));
461 assertEquals(bigOne, ArithmeticUtils.pow(twentyOne, BigInteger.valueOf(
462 103L)));
463
464 }
465
466 @Test
467 void testPowIntOverflow() {
468 assertThrows(MathRuntimeException.class, () -> {
469 ArithmeticUtils.pow(21, 8);
470 });
471 }
472
473 @Test
474 void testPowInt() {
475 final int base = 21;
476
477 assertEquals(85766121L,
478 ArithmeticUtils.pow(base, 6));
479 assertEquals(1801088541L,
480 ArithmeticUtils.pow(base, 7));
481 }
482
483 @Test
484 void testPowNegativeIntOverflow() {
485 assertThrows(MathRuntimeException.class, () -> {
486 ArithmeticUtils.pow(-21, 8);
487 });
488 }
489
490 @Test
491 void testPowNegativeInt() {
492 final int base = -21;
493
494 assertEquals(85766121,
495 ArithmeticUtils.pow(base, 6));
496 assertEquals(-1801088541,
497 ArithmeticUtils.pow(base, 7));
498 }
499
500 @Test
501 void testPowMinusOneInt() {
502 final int base = -1;
503 for (int i = 0; i < 100; i++) {
504 final int pow = ArithmeticUtils.pow(base, i);
505 assertEquals(i % 2 == 0 ? 1 : -1, pow, "i: " + i);
506 }
507 }
508
509 @Test
510 void testPowOneInt() {
511 final int base = 1;
512 for (int i = 0; i < 100; i++) {
513 final int pow = ArithmeticUtils.pow(base, i);
514 assertEquals(1, pow, "i: " + i);
515 }
516 }
517
518 @Test
519 void testPowLongOverflow() {
520 assertThrows(MathRuntimeException.class, () -> {
521 ArithmeticUtils.pow(21, 15);
522 });
523 }
524
525 @Test
526 void testPowLong() {
527 final long base = 21;
528
529 assertEquals(154472377739119461L,
530 ArithmeticUtils.pow(base, 13));
531 assertEquals(3243919932521508681L,
532 ArithmeticUtils.pow(base, 14));
533 }
534
535 @Test
536 void testPowNegativeLongOverflow() {
537 assertThrows(MathRuntimeException.class, () -> {
538 ArithmeticUtils.pow(-21L, 15);
539 });
540 }
541
542 @Test
543 void testPowNegativeLong() {
544 final long base = -21;
545
546 assertEquals(-154472377739119461L,
547 ArithmeticUtils.pow(base, 13));
548 assertEquals(3243919932521508681L,
549 ArithmeticUtils.pow(base, 14));
550 }
551
552 @Test
553 void testPowMinusOneLong() {
554 final long base = -1;
555 for (int i = 0; i < 100; i++) {
556 final long pow = ArithmeticUtils.pow(base, i);
557 assertEquals(i % 2 == 0 ? 1 : -1, pow, "i: " + i);
558 }
559 }
560
561 @Test
562 void testPowOneLong() {
563 final long base = 1;
564 for (int i = 0; i < 100; i++) {
565 final long pow = ArithmeticUtils.pow(base, i);
566 assertEquals(1, pow, "i: " + i);
567 }
568 }
569
570 @Test
571 void testIsPowerOfTwo() {
572 final int n = 1025;
573 final boolean[] expected = new boolean[n];
574 Arrays.fill(expected, false);
575 for (int i = 1; i < expected.length; i *= 2) {
576 expected[i] = true;
577 }
578 for (int i = 0; i < expected.length; i++) {
579 final boolean actual = ArithmeticUtils.isPowerOfTwo(i);
580 assertEquals(actual, expected[i], Integer.toString(i));
581 }
582 }
583
584 private void testAddAndCheckLongFailure(long a, long b) {
585 try {
586 ArithmeticUtils.addAndCheck(a, b);
587 fail("Expecting MathRuntimeException");
588 } catch (MathRuntimeException ex) {
589
590 }
591 }
592
593 private void testMulAndCheckLongFailure(long a, long b) {
594 try {
595 ArithmeticUtils.mulAndCheck(a, b);
596 fail("Expecting MathRuntimeException");
597 } catch (MathRuntimeException ex) {
598
599 }
600 }
601
602 private void testSubAndCheckLongFailure(long a, long b) {
603 try {
604 ArithmeticUtils.subAndCheck(a, b);
605 fail("Expecting MathRuntimeException");
606 } catch (MathRuntimeException ex) {
607
608 }
609 }
610
611
612
613
614
615
616
617
618
619
620 private static int[] getIntSpecialCases() {
621 int[] ints = new int[100];
622 int i = 0;
623 ints[i++] = Integer.MAX_VALUE;
624 ints[i++] = Integer.MAX_VALUE - 1;
625 ints[i++] = 100;
626 ints[i++] = 101;
627 ints[i++] = 102;
628 ints[i++] = 300;
629 ints[i++] = 567;
630 for (int j = 0; j < 20; j++) {
631 ints[i++] = j;
632 }
633 for (int j = i - 1; j >= 0; j--) {
634 ints[i++] = ints[j] > 0 ? -ints[j] : Integer.MIN_VALUE;
635 }
636 java.util.Random r = new java.util.Random(System.nanoTime());
637 while (i < ints.length) {
638 ints[i++] = r.nextInt();
639 }
640 return ints;
641 }
642
643
644
645
646
647
648
649
650
651
652
653
654 private static long[] getLongSpecialCases() {
655 long[] longs = new long[100];
656 int i = 0;
657 longs[i++] = Long.MAX_VALUE;
658 longs[i++] = Long.MAX_VALUE - 1L;
659 longs[i++] = (long) Integer.MAX_VALUE + 1L;
660 longs[i++] = Integer.MAX_VALUE;
661 longs[i++] = Integer.MAX_VALUE - 1;
662 longs[i++] = 100L;
663 longs[i++] = 101L;
664 longs[i++] = 102L;
665 longs[i++] = 300L;
666 longs[i++] = 567L;
667 for (int j = 0; j < 20; j++) {
668 longs[i++] = j;
669 }
670 for (int j = i - 1; j >= 0; j--) {
671 longs[i++] = longs[j] > 0L ? -longs[j] : Long.MIN_VALUE;
672 }
673 java.util.Random r = new java.util.Random(System.nanoTime());
674 while (i < longs.length) {
675 longs[i++] = r.nextLong();
676 }
677 return longs;
678 }
679
680 private static long toUnsignedLong(int number) {
681 return number < 0 ? 0x100000000L + (long)number : (long)number;
682 }
683
684 private static int remainderUnsignedExpected(int dividend, int divisor) {
685 return (int)remainderUnsignedExpected(toUnsignedLong(dividend), toUnsignedLong(divisor));
686 }
687
688 private static int divideUnsignedExpected(int dividend, int divisor) {
689 return (int)divideUnsignedExpected(toUnsignedLong(dividend), toUnsignedLong(divisor));
690 }
691
692 private static BigInteger toUnsignedBigInteger(long number) {
693 return number < 0L ? BigInteger.ONE.shiftLeft(64).add(BigInteger.valueOf(number)) : BigInteger.valueOf(number);
694 }
695
696 private static long remainderUnsignedExpected(long dividend, long divisor) {
697 return toUnsignedBigInteger(dividend).remainder(toUnsignedBigInteger(divisor)).longValue();
698 }
699
700 private static long divideUnsignedExpected(long dividend, long divisor) {
701 return toUnsignedBigInteger(dividend).divide(toUnsignedBigInteger(divisor)).longValue();
702 }
703
704 @Test
705 @Timeout(value = 5000L, unit = TimeUnit.MILLISECONDS)
706 void testRemainderUnsignedInt() {
707 assertEquals(36, ArithmeticUtils.remainderUnsigned(-2147479015, 63));
708 assertEquals(6, ArithmeticUtils.remainderUnsigned(-2147479015, 25));
709 }
710
711 @Test
712 @Timeout(value = 5000L, unit = TimeUnit.MILLISECONDS)
713 void testRemainderUnsignedIntSpecialCases() {
714 int[] ints = getIntSpecialCases();
715 for (int dividend : ints) {
716 for (int divisor : ints) {
717 if (divisor == 0) {
718 try {
719 ArithmeticUtils.remainderUnsigned(dividend, divisor);
720 fail("Should have failed with ArithmeticException: division by zero");
721 } catch (ArithmeticException e) {
722
723 }
724 } else {
725 assertEquals(remainderUnsignedExpected(dividend, divisor), ArithmeticUtils.remainderUnsigned(dividend, divisor));
726 }
727 }
728 }
729 }
730
731 @Test
732 @Timeout(value = 5000L, unit = TimeUnit.MILLISECONDS)
733 void testRemainderUnsignedLong() {
734 assertEquals(48L, ArithmeticUtils.remainderUnsigned(-2147479015L, 63L));
735 }
736
737
738 @Test
739 void testRemainderUnsignedLongSpecialCases() {
740 long[] longs = getLongSpecialCases();
741 for (long dividend : longs) {
742 for (long divisor : longs) {
743 if (divisor == 0L) {
744 try {
745 ArithmeticUtils.remainderUnsigned(dividend, divisor);
746 fail("Should have failed with ArithmeticException: division by zero");
747 } catch (ArithmeticException e) {
748
749 }
750 } else {
751 assertEquals(remainderUnsignedExpected(dividend, divisor), ArithmeticUtils.remainderUnsigned(dividend, divisor));
752 }
753 }
754 }
755 }
756
757 @Test
758 @Timeout(value = 5000L, unit = TimeUnit.MILLISECONDS)
759 void testDivideUnsignedInt() {
760 assertEquals(34087115, ArithmeticUtils.divideUnsigned(-2147479015, 63));
761 assertEquals(85899531, ArithmeticUtils.divideUnsigned(-2147479015, 25));
762 assertEquals(2147483646, ArithmeticUtils.divideUnsigned(-3, 2));
763 assertEquals(330382098, ArithmeticUtils.divideUnsigned(-16, 13));
764 assertEquals(306783377, ArithmeticUtils.divideUnsigned(-16, 14));
765 assertEquals(2, ArithmeticUtils.divideUnsigned(-1, 2147483647));
766 assertEquals(2, ArithmeticUtils.divideUnsigned(-2, 2147483647));
767 assertEquals(1, ArithmeticUtils.divideUnsigned(-3, 2147483647));
768 assertEquals(1, ArithmeticUtils.divideUnsigned(-16, 2147483647));
769 assertEquals(1, ArithmeticUtils.divideUnsigned(-16, 2147483646));
770 }
771
772 @Test
773 @Timeout(value = 5000L, unit = TimeUnit.MILLISECONDS)
774 void testDivideUnsignedIntSpecialCases() {
775 int[] ints = getIntSpecialCases();
776 for (int dividend : ints) {
777 for (int divisor : ints) {
778 if (divisor == 0) {
779 try {
780 ArithmeticUtils.divideUnsigned(dividend, divisor);
781 fail("Should have failed with ArithmeticException: division by zero");
782 } catch (ArithmeticException e) {
783
784 }
785 } else {
786 assertEquals(divideUnsignedExpected(dividend, divisor), ArithmeticUtils.divideUnsigned(dividend, divisor));
787 }
788 }
789 }
790 }
791
792 @Test
793 @Timeout(value = 5000L, unit = TimeUnit.MILLISECONDS)
794 void testDivideUnsignedLong() {
795 assertEquals(292805461453366231L, ArithmeticUtils.divideUnsigned(-2147479015L, 63L));
796 }
797
798 @Test
799 @Timeout(value = 5000L, unit = TimeUnit.MILLISECONDS)
800 void testDivideUnsignedLongSpecialCases() {
801 long[] longs = getLongSpecialCases();
802 for (long dividend : longs) {
803 for (long divisor : longs) {
804 if (divisor == 0L) {
805 try {
806 ArithmeticUtils.divideUnsigned(dividend, divisor);
807 fail("Should have failed with ArithmeticException: division by zero");
808 } catch (ArithmeticException e) {
809
810 }
811 } else {
812 assertEquals(divideUnsignedExpected(dividend, divisor), ArithmeticUtils.divideUnsigned(dividend, divisor));
813 }
814 }
815 }
816 }
817 }