1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.numbers.fraction;
18
19 import java.math.BigDecimal;
20 import java.math.BigInteger;
21 import java.math.RoundingMode;
22 import java.util.Arrays;
23 import org.apache.commons.numbers.core.TestUtils;
24
25 import org.junit.jupiter.api.Assertions;
26 import org.junit.jupiter.api.Test;
27
28
29
30
31 class BigFractionTest {
32
33
34 private static final BigFraction ZERO_P = BigFraction.of(0, 1);
35
36 private static final BigFraction ZERO_N = BigFraction.of(0, -1);
37
38 private static void assertFraction(int expectedNumerator, int expectedDenominator, BigFraction actual) {
39 Assertions.assertEquals(expectedNumerator, actual.getNumeratorAsInt());
40 Assertions.assertEquals(expectedDenominator, actual.getDenominatorAsInt());
41 Assertions.assertEquals(
42 Integer.signum(expectedNumerator) * Integer.signum(expectedDenominator),
43 actual.signum());
44 }
45
46 private static void assertFraction(long expectedNumerator, long expectedDenominator, BigFraction actual) {
47 Assertions.assertEquals(expectedNumerator, actual.getNumeratorAsLong());
48 Assertions.assertEquals(expectedDenominator, actual.getDenominatorAsLong());
49 Assertions.assertEquals(
50 Long.signum(expectedNumerator) * Long.signum(expectedDenominator),
51 actual.signum());
52 }
53
54 private static void assertFraction(BigInteger expectedNumerator, BigInteger expectedDenominator, BigFraction actual) {
55 Assertions.assertEquals(expectedNumerator, actual.getNumerator());
56 Assertions.assertEquals(expectedDenominator, actual.getDenominator());
57 Assertions.assertEquals(
58 expectedNumerator.signum() * expectedDenominator.signum(),
59 actual.signum());
60 }
61
62 private static void assertDoubleValue(double expected, BigInteger numerator, BigInteger denominator) {
63 final BigFraction f = BigFraction.of(numerator, denominator);
64 Assertions.assertEquals(expected, f.doubleValue());
65 }
66
67 private static void assertDoubleValue(double expected, long numerator, long denominator) {
68 assertDoubleValue(expected, BigInteger.valueOf(numerator), BigInteger.valueOf(denominator));
69 }
70
71 @Test
72 void testConstructor() {
73 for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.numDenConstructorTestCases()) {
74 assertFraction(
75 testCase.expectedNumerator,
76 testCase.expectedDenominator,
77 BigFraction.of(testCase.operandNumerator, testCase.operandDenominator)
78 );
79 }
80
81
82 assertFraction(0, 1, BigFraction.of(0L, 2L));
83 assertFraction(1L, 1, BigFraction.of(1L));
84 assertFraction(11, 1, BigFraction.of(11L));
85 assertFraction(11, 1, BigFraction.of(new BigInteger("11")));
86
87
88 Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(BigInteger.ONE, BigInteger.ZERO));
89
90
91 Assertions.assertThrows(NullPointerException.class, () -> BigFraction.of(null, BigInteger.ONE));
92 Assertions.assertThrows(NullPointerException.class, () -> BigFraction.of(BigInteger.ONE, null));
93 Assertions.assertThrows(NullPointerException.class, () -> BigFraction.of(null));
94
95 Assertions.assertThrows(ArithmeticException.class,
96 () -> BigFraction.from(2.0 * Integer.MAX_VALUE, 1.0e-5, 100000));
97 }
98
99 @Test
100 void testConstructorZero() {
101 Assertions.assertSame(BigFraction.ZERO, BigFraction.from(0.0));
102 Assertions.assertSame(BigFraction.ZERO, BigFraction.from(0.0, 1e-10, 100));
103 Assertions.assertSame(BigFraction.ZERO, BigFraction.from(0.0, 100));
104 Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0));
105 Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0L));
106 Assertions.assertSame(BigFraction.ZERO, BigFraction.of(BigInteger.ZERO));
107 Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0, 1));
108 Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0, -1));
109 Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0L, 1L));
110 Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0L, -1L));
111 Assertions.assertSame(BigFraction.ZERO, BigFraction.of(BigInteger.ZERO, BigInteger.ONE));
112 Assertions.assertSame(BigFraction.ZERO, BigFraction.of(BigInteger.ZERO, BigInteger.ONE.negate()));
113 }
114
115
116 @Test
117 void testDoubleConstructor() {
118 for (final CommonTestCases.DoubleToFractionTestCase testCase : CommonTestCases.doubleConstructorTestCases()) {
119 assertFraction(
120 testCase.expectedNumerator,
121 testCase.expectedDenominator,
122 BigFraction.from(testCase.operand, 1.0e-5, 100)
123 );
124 }
125
126
127 assertFraction(6004799503160661L, 18014398509481984L, BigFraction.from(1.0 / 3.0));
128 assertFraction(6124895493223875L, 36028797018963968L, BigFraction.from(17.0 / 100.0));
129 assertFraction(1784551352345559L, 562949953421312L, BigFraction.from(317.0 / 100.0));
130 assertFraction(-6004799503160661L, 18014398509481984L, BigFraction.from(-1.0 / 3.0));
131 assertFraction(-6124895493223875L, 36028797018963968L, BigFraction.from(17.0 / -100.0));
132 assertFraction(-1784551352345559L, 562949953421312L, BigFraction.from(-317.0 / 100.0));
133
134
135 Assertions.assertEquals(1L, BigFraction.from(Double.MAX_VALUE).getDenominatorAsLong());
136 Assertions.assertEquals(1L, BigFraction.from(Double.longBitsToDouble(0x0010000000000000L)).getNumeratorAsLong());
137 assertFraction(BigInteger.ONE, BigInteger.ONE.shiftLeft(1074), BigFraction.from(Double.MIN_VALUE));
138
139
140 Assertions.assertEquals(0.00000000000001, BigFraction.from(0.00000000000001).doubleValue());
141 Assertions.assertEquals(0.40000000000001, BigFraction.from(0.40000000000001).doubleValue());
142 Assertions.assertEquals(15.0000000000001, BigFraction.from(15.0000000000001).doubleValue());
143
144 assertFraction(3602879701896487L, 9007199254740992L, BigFraction.from(0.40000000000001));
145 assertFraction(1055531162664967L, 70368744177664L, BigFraction.from(15.0000000000001));
146 }
147
148
149
150 @Test
151 void testDoubleConstructorWithMaxDenominator() {
152 for (final CommonTestCases.DoubleToFractionTestCase testCase : CommonTestCases.doubleMaxDenomConstructorTestCases()) {
153 assertFraction(
154 testCase.expectedNumerator,
155 testCase.expectedDenominator,
156 BigFraction.from(testCase.operand, testCase.maxDenominator)
157 );
158 }
159
160
161 final long pow31 = 1L << 31;
162 assertFraction(pow31, 1, BigFraction.from(Integer.MIN_VALUE * -1.0, 2));
163 assertFraction(pow31, 3, BigFraction.from(Integer.MIN_VALUE / -3.0, 10));
164 assertFraction(-1, pow31, BigFraction.from(1.0 / Integer.MIN_VALUE, Integer.MIN_VALUE));
165 assertFraction(1, pow31, BigFraction.from(-1.0 / Integer.MIN_VALUE, Integer.MIN_VALUE));
166
167 Assertions.assertThrows(IllegalArgumentException.class, () -> BigFraction.from(1.0, 0));
168 }
169
170 @Test
171 void testDoubleConstructorThrows() {
172 final double eps = 1e-5;
173 final int maxIterations = Integer.MAX_VALUE;
174 final int maxDenominator = Integer.MAX_VALUE;
175 for (final double value : new double[] {Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY}) {
176 Assertions.assertThrows(IllegalArgumentException.class, () -> BigFraction.from(value));
177 Assertions.assertThrows(IllegalArgumentException.class, () -> BigFraction.from(value, eps, maxIterations));
178 Assertions.assertThrows(IllegalArgumentException.class, () -> BigFraction.from(value, maxDenominator));
179 }
180 Assertions.assertThrows(IllegalArgumentException.class, () -> BigFraction.from(1.0, Double.NaN, maxIterations));
181 Assertions.assertThrows(IllegalArgumentException.class, () -> BigFraction.from(1.0, -1.0, maxIterations));
182 Assertions.assertThrows(IllegalArgumentException.class, () -> BigFraction.from(1.0, eps, 0));
183
184 assertFraction(1, 1, BigFraction.from(1.0, 0, maxIterations));
185 }
186
187 @Test
188 void testDoubleConstructorGoldenRatioThrows() {
189
190 Assertions.assertThrows(FractionException.class,
191 () -> BigFraction.from((1 + Math.sqrt(5)) / 2, 1.0e-12, 25)
192 );
193 }
194
195
196 @Test
197 void testDoubleConstructorWithMaxDenominatorOverFlow() {
198 Assertions.assertThrows(ArithmeticException.class,
199 () -> BigFraction.from(1e10, 1000)
200 );
201 Assertions.assertThrows(ArithmeticException.class,
202 () -> BigFraction.from(-1e10, 1000)
203 );
204 }
205
206 @Test
207 void testDoubleConstructorOverflow() {
208 assertDoubleConstructorOverflow(0.75000000001455192);
209 assertDoubleConstructorOverflow(1.0e10);
210 assertDoubleConstructorOverflow(-1.0e10);
211 assertDoubleConstructorOverflow(-43979.60679604749);
212 }
213
214 private void assertDoubleConstructorOverflow(final double a) {
215 Assertions.assertThrows(ArithmeticException.class,
216 () -> BigFraction.from(a, 1.0e-12, 1000)
217 );
218 }
219
220 @Test
221 void testDoubleConstructorWithEpsilonLimit() {
222 assertFraction(2, 5, BigFraction.from(0.4, 1.0e-5, 100));
223
224 assertFraction(3, 5, BigFraction.from(0.6152, 0.02, 100));
225 assertFraction(8, 13, BigFraction.from(0.6152, 1.0e-3, 100));
226 assertFraction(251, 408, BigFraction.from(0.6152, 1.0e-4, 100));
227 assertFraction(251, 408, BigFraction.from(0.6152, 1.0e-5, 100));
228 assertFraction(510, 829, BigFraction.from(0.6152, 1.0e-6, 100));
229 assertFraction(769, 1250, BigFraction.from(0.6152, 1.0e-7, 100));
230 }
231
232 @Test
233 void testCompareTo() {
234 final BigFraction a = BigFraction.of(1, 2);
235 final BigFraction b = BigFraction.of(1, 3);
236 final BigFraction c = BigFraction.of(1, 2);
237 final BigFraction d = BigFraction.of(-1, 2);
238 final BigFraction e = BigFraction.of(1, -2);
239 final BigFraction f = BigFraction.of(-1, -2);
240 final BigFraction g = BigFraction.of(-1, Integer.MIN_VALUE);
241
242 Assertions.assertEquals(0, a.compareTo(a));
243 Assertions.assertEquals(0, a.compareTo(c));
244 Assertions.assertEquals(1, a.compareTo(b));
245 Assertions.assertEquals(-1, b.compareTo(a));
246 Assertions.assertEquals(-1, d.compareTo(a));
247 Assertions.assertEquals(1, a.compareTo(d));
248 Assertions.assertEquals(-1, e.compareTo(a));
249 Assertions.assertEquals(1, a.compareTo(e));
250 Assertions.assertEquals(0, d.compareTo(e));
251 Assertions.assertEquals(0, a.compareTo(f));
252 Assertions.assertEquals(0, f.compareTo(a));
253 Assertions.assertEquals(1, f.compareTo(e));
254 Assertions.assertEquals(-1, e.compareTo(f));
255 Assertions.assertEquals(-1, g.compareTo(a));
256 Assertions.assertEquals(-1, g.compareTo(f));
257 Assertions.assertEquals(1, a.compareTo(g));
258 Assertions.assertEquals(-1, d.compareTo(g));
259
260 Assertions.assertEquals(0, BigFraction.of(0, 3).compareTo(BigFraction.of(0, -2)));
261
262
263
264
265 final BigFraction pi1 = BigFraction.of(1068966896, 340262731);
266 final BigFraction pi2 = BigFraction.of(411557987, 131002976);
267 Assertions.assertEquals(-1, pi1.compareTo(pi2));
268 Assertions.assertEquals(1, pi2.compareTo(pi1));
269 Assertions.assertEquals(0.0, pi1.doubleValue() - pi2.doubleValue(), 1.0e-20);
270
271 Assertions.assertEquals(0, ZERO_P.compareTo(ZERO_N));
272 }
273
274 @Test
275 void testDoubleValue() {
276 assertDoubleValue(0.5, 1, 2);
277 assertDoubleValue(-0.5, -1, 2);
278 assertDoubleValue(-0.5, 1, -2);
279 assertDoubleValue(0.5, -1, -2);
280 assertDoubleValue(1.0 / 3.0, 1, 3);
281
282 Assertions.assertEquals(0.0, BigFraction.ZERO.doubleValue());
283 Assertions.assertEquals(0.0, ZERO_P.doubleValue());
284 Assertions.assertEquals(0.0, ZERO_N.doubleValue());
285
286
287 assertDoubleValue(
288 2d - 0x1P-52,
289 1L << 54,
290 (1L << 53) + 1L
291 );
292
293 assertDoubleValue(
294 2d,
295 (1L << 54) - 1L,
296 1L << 53
297 );
298 assertDoubleValue(
299 1d,
300 (1L << 53) + 1L,
301 1L << 53
302 );
303 }
304
305 @Test
306 void testDoubleValueForSubnormalNumbers() {
307 assertDoubleValue(
308
309 Double.MIN_VALUE,
310 BigInteger.ONE,
311 BigInteger.ONE.shiftLeft(1073).multiply(BigInteger.valueOf(3L))
312 );
313
314 assertDoubleValue(
315 Double.MIN_VALUE,
316 BigInteger.ONE,
317 BigInteger.ONE.shiftLeft(1074)
318 );
319 assertDoubleValue(
320 Double.MIN_VALUE * 2,
321 BigInteger.valueOf(2),
322 BigInteger.ONE.shiftLeft(1074)
323 );
324 assertDoubleValue(
325 Double.MIN_VALUE * 3,
326 BigInteger.valueOf(3),
327 BigInteger.ONE.shiftLeft(1074)
328 );
329
330 assertDoubleValue(
331 Double.MIN_NORMAL - Double.MIN_VALUE,
332 BigInteger.ONE.shiftLeft(52).subtract(BigInteger.ONE),
333 BigInteger.ONE.shiftLeft(1074)
334 );
335 assertDoubleValue(
336 Double.MIN_NORMAL - 2 * Double.MIN_VALUE,
337 BigInteger.ONE.shiftLeft(52).subtract(BigInteger.valueOf(2)),
338 BigInteger.ONE.shiftLeft(1074)
339 );
340
341
342 assertDoubleValue(
343 Double.MIN_NORMAL,
344 BigInteger.ONE.shiftLeft(53).subtract(BigInteger.ONE),
345 BigInteger.ONE.shiftLeft(1075)
346 );
347 }
348
349 @Test
350 void testDoubleValueForInfinities() {
351
352 final BigInteger minInf = BigInteger.ONE
353 .shiftLeft(1024)
354 .subtract(BigInteger.ONE.shiftLeft(970));
355
356 assertDoubleValue(
357 Double.NEGATIVE_INFINITY,
358 minInf.negate(),
359 BigInteger.ONE
360 );
361 assertDoubleValue(
362 Double.POSITIVE_INFINITY,
363 minInf,
364 BigInteger.ONE
365 );
366 }
367
368
369 @Test
370 void testDoubleValueForLargeNumeratorAndDenominator() {
371 final BigInteger pow400 = BigInteger.TEN.pow(400);
372 final BigInteger pow401 = BigInteger.TEN.pow(401);
373 final BigInteger two = new BigInteger("2");
374 final BigFraction large = BigFraction.of(pow401.add(BigInteger.ONE),
375 pow400.multiply(two));
376
377 Assertions.assertEquals(5, large.doubleValue(), 1e-15);
378 }
379
380
381 @Test
382 void testFloatValueForLargeNumeratorAndDenominator() {
383 final BigInteger pow400 = BigInteger.TEN.pow(400);
384 final BigInteger pow401 = BigInteger.TEN.pow(401);
385 final BigInteger two = new BigInteger("2");
386 final BigFraction large = BigFraction.of(pow401.add(BigInteger.ONE),
387 pow400.multiply(two));
388
389 Assertions.assertEquals(5, large.floatValue(), 1e-15);
390 }
391
392 @Test
393 void testDoubleValueForLargeNumeratorAndSmallDenominator() {
394
395 final BigInteger pow300 = BigInteger.TEN.pow(300);
396 final BigInteger pow330 = BigInteger.TEN.pow(330);
397 final BigFraction large = BigFraction.of(pow330.add(BigInteger.ONE),
398 pow300);
399
400 Assertions.assertEquals(1e30, large.doubleValue(), 1e-15);
401
402
403 assertDoubleValue(
404 5.992310449541053E307,
405 BigInteger.ONE
406 .shiftLeft(1024)
407 .subtract(BigInteger.ONE.shiftLeft(970))
408 .add(BigInteger.ONE),
409 BigInteger.valueOf(3)
410 );
411
412 assertDoubleValue(
413 Double.MAX_VALUE,
414 BigInteger.ONE
415 .shiftLeft(1025)
416 .subtract(BigInteger.ONE.shiftLeft(972))
417 .subtract(BigInteger.ONE),
418 BigInteger.valueOf(2)
419 );
420 }
421
422
423 @Test
424 void testFloatValueForLargeNumeratorAndSmallDenominator() {
425 final BigInteger pow30 = BigInteger.TEN.pow(30);
426 final BigInteger pow40 = BigInteger.TEN.pow(40);
427 final BigFraction large = BigFraction.of(pow40.add(BigInteger.ONE),
428 pow30);
429
430 Assertions.assertEquals(1e10f, large.floatValue(), 1e-15);
431 }
432
433 @Test
434 void testFloatValue() {
435 Assertions.assertEquals(0.5f, BigFraction.of(1, 2).floatValue());
436 Assertions.assertEquals(0.5f, BigFraction.of(-1, -2).floatValue());
437 Assertions.assertEquals(-0.5f, BigFraction.of(-1, 2).floatValue());
438 Assertions.assertEquals(-0.5f, BigFraction.of(1, -2).floatValue());
439
440 final float e = 1f / 3f;
441 Assertions.assertEquals(e, BigFraction.of(1, 3).floatValue());
442 Assertions.assertEquals(e, BigFraction.of(-1, -3).floatValue());
443 Assertions.assertEquals(-e, BigFraction.of(-1, 3).floatValue());
444 Assertions.assertEquals(-e, BigFraction.of(1, -3).floatValue());
445
446 Assertions.assertEquals(0.0f, ZERO_P.floatValue());
447 Assertions.assertEquals(0.0f, ZERO_N.floatValue());
448 }
449
450 @Test
451 void testIntValue() {
452 Assertions.assertEquals(0, BigFraction.of(1, 2).intValue());
453 Assertions.assertEquals(0, BigFraction.of(-1, -2).intValue());
454 Assertions.assertEquals(0, BigFraction.of(-1, 2).intValue());
455 Assertions.assertEquals(0, BigFraction.of(1, -2).intValue());
456
457 Assertions.assertEquals(1, BigFraction.of(3, 2).intValue());
458 Assertions.assertEquals(1, BigFraction.of(-3, -2).intValue());
459 Assertions.assertEquals(-1, BigFraction.of(-3, 2).intValue());
460 Assertions.assertEquals(-1, BigFraction.of(3, -2).intValue());
461
462 Assertions.assertEquals(0, ZERO_P.intValue());
463 Assertions.assertEquals(0, ZERO_N.intValue());
464 }
465
466 @Test
467 void testLongValue() {
468 Assertions.assertEquals(0L, BigFraction.of(1, 2).longValue());
469 Assertions.assertEquals(0L, BigFraction.of(-1, -2).longValue());
470 Assertions.assertEquals(0L, BigFraction.of(-1, 2).longValue());
471 Assertions.assertEquals(0L, BigFraction.of(1, -2).longValue());
472
473 Assertions.assertEquals(1L, BigFraction.of(3, 2).longValue());
474 Assertions.assertEquals(1L, BigFraction.of(-3, -2).longValue());
475 Assertions.assertEquals(-1L, BigFraction.of(-3, 2).longValue());
476 Assertions.assertEquals(-1L, BigFraction.of(3, -2).longValue());
477
478 Assertions.assertEquals(0, ZERO_P.longValue());
479 Assertions.assertEquals(0, ZERO_N.longValue());
480 }
481
482 @Test
483 void testBigDecimalValue() {
484 Assertions.assertEquals(new BigDecimal(0.5), BigFraction.of(1, 2).bigDecimalValue());
485 Assertions.assertEquals(new BigDecimal("0.0003"), BigFraction.of(3, 10000).bigDecimalValue());
486 Assertions.assertEquals(new BigDecimal("0"), BigFraction.of(1, 3).bigDecimalValue(RoundingMode.DOWN));
487 Assertions.assertEquals(new BigDecimal("0.333"), BigFraction.of(1, 3).bigDecimalValue(3, RoundingMode.DOWN));
488 }
489
490 @Test
491 void testAbs() {
492 for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.absTestCases()) {
493 final BigFraction f = BigFraction.of(testCase.operandNumerator, testCase.operandDenominator);
494 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f.abs());
495 }
496 }
497
498 @Test
499 void testReciprocal() {
500 for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.reciprocalTestCases()) {
501 final BigFraction f = BigFraction.of(testCase.operandNumerator, testCase.operandDenominator);
502 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f.reciprocal());
503 }
504
505 final BigFraction f = BigFraction.of(0, 3);
506 Assertions.assertThrows(ArithmeticException.class, f::reciprocal);
507 }
508
509 @Test
510 void testNegate() {
511 for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.negateTestCases()) {
512 final BigFraction f = BigFraction.of(testCase.operandNumerator, testCase.operandDenominator);
513 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f.negate());
514 }
515 }
516
517 @Test
518 void testAdd() {
519 for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.addFractionTestCases()) {
520 final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
521 final BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
522 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(f2));
523 }
524 for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.addIntTestCases()) {
525 final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
526 final int i2 = testCase.secondOperand;
527 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(i2));
528 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add((long) i2));
529 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(BigInteger.valueOf(i2)));
530 }
531
532 Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.add((BigFraction) null));
533 Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.add((BigInteger) null));
534
535
536 final BigFraction f2 = BigFraction.of(1, 2);
537 assertFraction(1, 2, f2.add(BigInteger.ZERO));
538 assertFraction(12, 1, BigFraction.ZERO.add(BigInteger.valueOf(12)));
539 }
540
541 @Test
542 void testDivide() {
543 for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.divideByFractionTestCases()) {
544 final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
545 final BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
546 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(f2));
547 }
548 for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.divideByIntTestCases()) {
549 final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
550 final int i2 = testCase.secondOperand;
551 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(i2));
552 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide((long) i2));
553 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(BigInteger.valueOf(i2)));
554 }
555
556 Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.divide((BigFraction) null));
557 Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.divide((BigInteger) null));
558
559 Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(BigFraction.ZERO));
560 Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(0));
561 Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(0L));
562 Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(BigInteger.ZERO));
563
564
565 final BigFraction f1 = BigFraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
566 assertFraction(-1, -Integer.MAX_VALUE, f1.divide(Integer.MIN_VALUE));
567 assertFraction(-1, -Integer.MAX_VALUE, f1.divide((long) Integer.MIN_VALUE));
568 assertFraction(-1, -Integer.MAX_VALUE, f1.divide(BigInteger.valueOf(Integer.MIN_VALUE)));
569 }
570
571 @Test
572 void testMultiply() {
573 for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.multiplyByFractionTestCases()) {
574 final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
575 final BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
576 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(f2));
577 }
578 for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.multiplyByIntTestCases()) {
579 final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
580 final int i2 = testCase.secondOperand;
581 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(i2));
582 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply((long) i2));
583 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(BigInteger.valueOf(i2)));
584 }
585
586 Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.multiply((BigFraction) null));
587 Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.multiply((BigInteger) null));
588 }
589
590 @Test
591 void testPow() {
592 for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.powTestCases()) {
593 final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
594 final int exponent = testCase.secondOperand;
595 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow(exponent));
596 }
597
598
599
600 Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(2).pow(Integer.MAX_VALUE));
601 Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(1, 2).pow(Integer.MAX_VALUE));
602 Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(2).pow(-Integer.MAX_VALUE));
603 Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(1, 2).pow(-Integer.MAX_VALUE));
604 }
605
606 @Test
607 void testSubtract() {
608 for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.subtractFractionTestCases()) {
609 final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
610 final BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
611 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(f2));
612 }
613 for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.subtractIntTestCases()) {
614 final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
615 final int i2 = testCase.secondOperand;
616 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(i2));
617 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract((long) i2));
618 assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(BigInteger.valueOf(i2)));
619 }
620
621 Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.subtract((BigFraction) null));
622 Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.subtract((BigInteger) null));
623 }
624
625 @Test
626 void testEqualsAndHashCode() {
627 final BigFraction zero = BigFraction.of(0, 1);
628 Assertions.assertEquals(zero, zero);
629 Assertions.assertNotEquals(zero, null);
630 Assertions.assertNotEquals(zero, new Object());
631 Assertions.assertNotEquals(zero, Double.valueOf(0));
632
633
634 final BigFraction zero2 = BigFraction.of(0, 2);
635 assertEqualAndHashCodeEqual(zero, zero2);
636
637
638 final BigFraction one = BigFraction.of(1, 1);
639 Assertions.assertNotEquals(zero, one);
640 Assertions.assertNotEquals(one, zero);
641
642
643
644 for (final int[] f : new int[][] {{1, 1}, {2, 3}, {6826, 15373}, {1373, 103813}, {0, 3}}) {
645 final int num = f[0];
646 final int den = f[1];
647 BigFraction f1 = BigFraction.of(-num, den);
648 BigFraction f2 = BigFraction.of(num, -den);
649 assertEqualAndHashCodeEqual(f1, f2);
650 assertEqualAndHashCodeEqual(f2, f1);
651 f1 = BigFraction.of(num, den);
652 f2 = BigFraction.of(-num, -den);
653 assertEqualAndHashCodeEqual(f1, f2);
654 assertEqualAndHashCodeEqual(f2, f1);
655 }
656
657
658 final BigFraction half = BigFraction.of(1, 2);
659 final BigFraction two = BigFraction.of(2, 1);
660 Assertions.assertNotEquals(one, half);
661 Assertions.assertNotEquals(one, two);
662 }
663
664
665
666
667
668
669
670
671
672
673
674
675
676 private static void assertEqualAndHashCodeEqual(BigFraction f1, BigFraction f2) {
677 Assertions.assertEquals(f1, f2);
678 Assertions.assertEquals(f1.hashCode(), f2.hashCode(), "Equal fractions have different hashCode");
679
680
681 final int expected = f1.signum() *
682 Arrays.hashCode(new Object[] {f1.getNumerator().abs(),
683 f1.getDenominator().abs()});
684 Assertions.assertEquals(expected, f1.hashCode(), "Hashcode not equal to using Arrays.hashCode");
685 }
686
687 @Test
688 void testAdditiveNeutral() {
689 Assertions.assertEquals(BigFraction.ZERO, BigFraction.ONE.zero());
690 }
691
692 @Test
693 void testMultiplicativeNeutral() {
694 Assertions.assertEquals(BigFraction.ONE, BigFraction.ZERO.one());
695 }
696
697 @Test
698 void testSerial() {
699 final BigFraction[] fractions = {
700 BigFraction.of(3, 4), BigFraction.ONE, BigFraction.ZERO,
701 BigFraction.of(17), BigFraction.from(Math.PI, 1000),
702 BigFraction.of(-5, 2)
703 };
704 for (final BigFraction fraction : fractions) {
705 Assertions.assertEquals(fraction,
706 TestUtils.serializeAndRecover(fraction));
707 }
708 }
709
710 @Test
711 void testToString() {
712 Assertions.assertEquals("0", BigFraction.of(0, 3).toString());
713 Assertions.assertEquals("0", BigFraction.of(0, -3).toString());
714 Assertions.assertEquals("3", BigFraction.of(6, 2).toString());
715 Assertions.assertEquals("2 / 3", BigFraction.of(18, 27).toString());
716 Assertions.assertEquals("-10 / 11", BigFraction.of(-10, 11).toString());
717 Assertions.assertEquals("10 / -11", BigFraction.of(10, -11).toString());
718 }
719
720 @Test
721 void testParse() {
722 final String[] validExpressions = new String[] {
723 "1 / 2",
724 "-1 / 2",
725 "1 / -2",
726 "-1 / -2",
727 "01 / 2",
728 "01 / 02",
729 "-01 / 02",
730 "01 / -02",
731 "15 / 16",
732 "-2 / 3",
733 "8 / 7",
734 "5",
735 "-3",
736 "-3",
737 "2147,483,647 / 2,147,483,648",
738 "9,223,372,036,854,775,807 / 9,223,372,036,854,775,808"
739 };
740 final BigFraction[] fractions = {
741 BigFraction.of(1, 2),
742 BigFraction.of(-1, 2),
743 BigFraction.of(1, -2),
744 BigFraction.of(-1, -2),
745 BigFraction.of(1, 2),
746 BigFraction.of(1, 2),
747 BigFraction.of(-1, 2),
748 BigFraction.of(1, -2),
749 BigFraction.of(15, 16),
750 BigFraction.of(-2, 3),
751 BigFraction.of(8, 7),
752 BigFraction.of(5, 1),
753 BigFraction.of(-3, 1),
754 BigFraction.of(3, -1),
755 BigFraction.of(2147483647, 2147483648L),
756 BigFraction.of(new BigInteger("9223372036854775807"),
757 new BigInteger("9223372036854775808"))
758 };
759 int inc = 0;
760 for (final BigFraction fraction: fractions) {
761 Assertions.assertEquals(fraction,
762 BigFraction.parse(validExpressions[inc]));
763 inc++;
764 }
765
766 Assertions.assertThrows(NumberFormatException.class, () -> BigFraction.parse("1 // 2"));
767 Assertions.assertThrows(NumberFormatException.class, () -> BigFraction.parse("1 / z"));
768 Assertions.assertThrows(NumberFormatException.class, () -> BigFraction.parse("1 / --2"));
769 Assertions.assertThrows(NumberFormatException.class, () -> BigFraction.parse("x"));
770 }
771
772 @Test
773 void testMath340() {
774 final BigFraction fractionA = BigFraction.from(0.00131);
775 final BigFraction fractionB = BigFraction.from(.37).reciprocal();
776 final BigFraction errorResult = fractionA.multiply(fractionB);
777 final BigFraction correctResult = BigFraction.of(fractionA.getNumerator().multiply(fractionB.getNumerator()),
778 fractionA.getDenominator().multiply(fractionB.getDenominator()));
779 Assertions.assertEquals(correctResult, errorResult);
780 }
781
782 @Test
783 void testNumbers150() {
784
785 Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.ZERO.pow(-1));
786 Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.ZERO.pow(Integer.MIN_VALUE));
787
788
789 final BigFraction f2 = BigFraction.of(2);
790 Assertions.assertThrows(ArithmeticException.class, () -> f2.pow(Integer.MIN_VALUE));
791 final BigFraction f12 = BigFraction.of(1, 2);
792 Assertions.assertThrows(ArithmeticException.class, () -> f12.pow(Integer.MIN_VALUE));
793 }
794 }