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