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.fraction;
23
24 import org.hipparchus.UnitTestUtils;
25 import org.hipparchus.exception.MathIllegalStateException;
26 import org.hipparchus.exception.MathRuntimeException;
27 import org.hipparchus.exception.NullArgumentException;
28 import org.hipparchus.util.FastMath;
29 import org.hipparchus.util.Precision;
30 import org.junit.jupiter.api.Test;
31
32 import java.util.List;
33 import java.util.stream.Collectors;
34
35 import static org.junit.jupiter.api.Assertions.assertEquals;
36 import static org.junit.jupiter.api.Assertions.assertFalse;
37 import static org.junit.jupiter.api.Assertions.assertNotEquals;
38 import static org.junit.jupiter.api.Assertions.assertSame;
39 import static org.junit.jupiter.api.Assertions.assertThrows;
40 import static org.junit.jupiter.api.Assertions.assertTrue;
41 import static org.junit.jupiter.api.Assertions.fail;
42
43
44
45
46 class FractionTest {
47
48 private void customAssertFraction(int expectedNumerator, int expectedDenominator, Fraction actual) {
49 assertEquals(expectedNumerator, actual.getNumerator());
50 assertEquals(expectedDenominator, actual.getDenominator());
51 }
52
53 @Test
54 void testConstructor() {
55 customAssertFraction(0, 1, new Fraction(0, 1));
56 customAssertFraction(0, 1, new Fraction(0, 2));
57 customAssertFraction(0, 1, new Fraction(0, -1));
58 customAssertFraction(1, 2, new Fraction(1, 2));
59 customAssertFraction(1, 2, new Fraction(2, 4));
60 customAssertFraction(-1, 2, new Fraction(-1, 2));
61 customAssertFraction(-1, 2, new Fraction(1, -2));
62 customAssertFraction(-1, 2, new Fraction(-2, 4));
63 customAssertFraction(-1, 2, new Fraction(2, -4));
64
65
66 try {
67 new Fraction(Integer.MIN_VALUE, -1);
68 fail();
69 } catch (MathRuntimeException ex) {
70
71 }
72 try {
73 new Fraction(1, Integer.MIN_VALUE);
74 fail();
75 } catch (MathRuntimeException ex) {
76
77 }
78
79 customAssertFraction(0, 1, new Fraction(0.00000000000001));
80 customAssertFraction(2, 5, new Fraction(0.40000000000001));
81 customAssertFraction(15, 1, new Fraction(15.0000000000001));
82 }
83
84 @Test
85 void testIsInteger() {
86 assertTrue(new Fraction(12, 12).isInteger());
87 assertTrue(new Fraction(14, 7).isInteger());
88 assertFalse(new Fraction(12, 11).isInteger());
89 }
90
91 @Test
92 void testGoldenRatio() {
93 assertThrows(MathIllegalStateException.class, () -> {
94
95 new Fraction((1 + FastMath.sqrt(5)) / 2, 1.0e-12, 25);
96 });
97 }
98
99
100 @Test
101 void testDoubleConstructor() {
102 customAssertFraction(1, 2, new Fraction((double)1 / (double)2));
103 customAssertFraction(1, 3, new Fraction((double)1 / (double)3));
104 customAssertFraction(2, 3, new Fraction((double)2 / (double)3));
105 customAssertFraction(1, 4, new Fraction((double)1 / (double)4));
106 customAssertFraction(3, 4, new Fraction((double)3 / (double)4));
107 customAssertFraction(1, 5, new Fraction((double)1 / (double)5));
108 customAssertFraction(2, 5, new Fraction((double)2 / (double)5));
109 customAssertFraction(3, 5, new Fraction((double)3 / (double)5));
110 customAssertFraction(4, 5, new Fraction((double)4 / (double)5));
111 customAssertFraction(1, 6, new Fraction((double)1 / (double)6));
112 customAssertFraction(5, 6, new Fraction((double)5 / (double)6));
113 customAssertFraction(1, 7, new Fraction((double)1 / (double)7));
114 customAssertFraction(2, 7, new Fraction((double)2 / (double)7));
115 customAssertFraction(3, 7, new Fraction((double)3 / (double)7));
116 customAssertFraction(4, 7, new Fraction((double)4 / (double)7));
117 customAssertFraction(5, 7, new Fraction((double)5 / (double)7));
118 customAssertFraction(6, 7, new Fraction((double)6 / (double)7));
119 customAssertFraction(1, 8, new Fraction((double)1 / (double)8));
120 customAssertFraction(3, 8, new Fraction((double)3 / (double)8));
121 customAssertFraction(5, 8, new Fraction((double)5 / (double)8));
122 customAssertFraction(7, 8, new Fraction((double)7 / (double)8));
123 customAssertFraction(1, 9, new Fraction((double)1 / (double)9));
124 customAssertFraction(2, 9, new Fraction((double)2 / (double)9));
125 customAssertFraction(4, 9, new Fraction((double)4 / (double)9));
126 customAssertFraction(5, 9, new Fraction((double)5 / (double)9));
127 customAssertFraction(7, 9, new Fraction((double)7 / (double)9));
128 customAssertFraction(8, 9, new Fraction((double)8 / (double)9));
129 customAssertFraction(1, 10, new Fraction((double)1 / (double)10));
130 customAssertFraction(3, 10, new Fraction((double)3 / (double)10));
131 customAssertFraction(7, 10, new Fraction((double)7 / (double)10));
132 customAssertFraction(9, 10, new Fraction((double)9 / (double)10));
133 customAssertFraction(1, 11, new Fraction((double)1 / (double)11));
134 customAssertFraction(2, 11, new Fraction((double)2 / (double)11));
135 customAssertFraction(3, 11, new Fraction((double)3 / (double)11));
136 customAssertFraction(4, 11, new Fraction((double)4 / (double)11));
137 customAssertFraction(5, 11, new Fraction((double)5 / (double)11));
138 customAssertFraction(6, 11, new Fraction((double)6 / (double)11));
139 customAssertFraction(7, 11, new Fraction((double)7 / (double)11));
140 customAssertFraction(8, 11, new Fraction((double)8 / (double)11));
141 customAssertFraction(9, 11, new Fraction((double)9 / (double)11));
142 customAssertFraction(10, 11, new Fraction((double)10 / (double)11));
143 }
144
145
146 @Test
147 void testDigitLimitConstructor() {
148 customAssertFraction(2, 5, new Fraction(0.4, 9));
149 customAssertFraction(2, 5, new Fraction(0.4, 99));
150 customAssertFraction(2, 5, new Fraction(0.4, 999));
151
152 customAssertFraction(3, 5, new Fraction(0.6152, 9));
153 customAssertFraction(8, 13, new Fraction(0.6152, 99));
154 customAssertFraction(510, 829, new Fraction(0.6152, 999));
155 customAssertFraction(769, 1250, new Fraction(0.6152, 9999));
156
157
158 customAssertFraction(1, 2, new Fraction(0.5000000001, 10));
159 }
160
161 @Test
162 void testIntegerOverflow() {
163 checkIntegerOverflow(0.75000000001455192);
164 checkIntegerOverflow(1.0e10);
165 checkIntegerOverflow(-1.0e10);
166 }
167
168 @Test
169 void testSignum() {
170 assertEquals(-1, new Fraction(4, -5).signum());
171 assertEquals(-1, new Fraction(-4, 5).signum());
172 assertEquals( 0, new Fraction(0).signum());
173 assertEquals(+1, new Fraction(-4, -5).signum());
174 assertEquals(+1, new Fraction(4, 5).signum());
175 }
176
177 private void checkIntegerOverflow(double a) {
178 assertThrows(MathIllegalStateException.class, () -> new Fraction(a, 1.0e-12, 1000));
179 }
180
181 @Test
182 void testEpsilonLimitConstructor() {
183 customAssertFraction(2, 5, new Fraction(0.4, 1.0e-5, 100));
184
185 customAssertFraction(3, 5, new Fraction(0.6152, 0.02, 100));
186 customAssertFraction(8, 13, new Fraction(0.6152, 1.0e-3, 100));
187 customAssertFraction(251, 408, new Fraction(0.6152, 1.0e-4, 100));
188 customAssertFraction(251, 408, new Fraction(0.6152, 1.0e-5, 100));
189 customAssertFraction(510, 829, new Fraction(0.6152, 1.0e-6, 100));
190 customAssertFraction(769, 1250, new Fraction(0.6152, 1.0e-7, 100));
191 }
192
193 @Test
194 void testCompareTo() {
195 Fraction first = new Fraction(1, 2);
196 Fraction second = new Fraction(1, 3);
197 Fraction third = new Fraction(1, 2);
198
199 assertEquals(0, first.compareTo(first));
200 assertEquals(0, first.compareTo(third));
201 assertEquals(1, first.compareTo(second));
202 assertEquals(-1, second.compareTo(first));
203
204
205
206
207 Fraction pi1 = new Fraction(1068966896, 340262731);
208 Fraction pi2 = new Fraction( 411557987, 131002976);
209 assertEquals(-1, pi1.compareTo(pi2));
210 assertEquals( 1, pi2.compareTo(pi1));
211 assertEquals(0.0, pi1.doubleValue() - pi2.doubleValue(), 1.0e-20);
212 }
213
214 @Test
215 void testDoubleValue() {
216 Fraction first = new Fraction(1, 2);
217 Fraction second = new Fraction(1, 3);
218
219 assertEquals(0.5, first.doubleValue(), 0.0);
220 assertEquals(1.0 / 3.0, second.doubleValue(), 0.0);
221 }
222
223 @Test
224 void testFloatValue() {
225 Fraction first = new Fraction(1, 2);
226 Fraction second = new Fraction(1, 3);
227
228 assertEquals(0.5f, first.floatValue(), 0.0f);
229 assertEquals((float)(1.0 / 3.0), second.floatValue(), 0.0f);
230 }
231
232 @Test
233 void testIntValue() {
234 Fraction first = new Fraction(1, 2);
235 Fraction second = new Fraction(3, 2);
236
237 assertEquals(0, first.intValue());
238 assertEquals(1, second.intValue());
239 }
240
241 @Test
242 void testLongValue() {
243 Fraction first = new Fraction(1, 2);
244 Fraction second = new Fraction(3, 2);
245
246 assertEquals(0L, first.longValue());
247 assertEquals(1L, second.longValue());
248 }
249
250 @Test
251 void testConstructorDouble() {
252 customAssertFraction(1, 2, new Fraction(0.5));
253 customAssertFraction(1, 3, new Fraction(1.0 / 3.0));
254 customAssertFraction(17, 100, new Fraction(17.0 / 100.0));
255 customAssertFraction(317, 100, new Fraction(317.0 / 100.0));
256 customAssertFraction(-1, 2, new Fraction(-0.5));
257 customAssertFraction(-1, 3, new Fraction(-1.0 / 3.0));
258 customAssertFraction(-17, 100, new Fraction(17.0 / -100.0));
259 customAssertFraction(-317, 100, new Fraction(-317.0 / 100.0));
260 }
261
262 @Test
263 void testAbs() {
264 Fraction a = new Fraction(10, 21);
265 Fraction b = new Fraction(-10, 21);
266 Fraction c = new Fraction(10, -21);
267
268 customAssertFraction(10, 21, a.abs());
269 customAssertFraction(10, 21, b.abs());
270 customAssertFraction(10, 21, c.abs());
271 }
272
273 @Test
274 void testPercentage() {
275 assertEquals(50.0, new Fraction(1, 2).percentageValue(), 1.0e-15);
276 }
277
278 @Test
279 void testMath835() {
280 final int numer = Integer.MAX_VALUE / 99;
281 final int denom = 1;
282 final double percentage = 100 * ((double) numer) / denom;
283 final Fraction frac = new Fraction(numer, denom);
284
285
286 assertEquals(percentage, frac.percentageValue(), Math.ulp(percentage));
287 }
288
289 @Test
290 void testMath1261() {
291 final Fraction a = new Fraction(Integer.MAX_VALUE, 2);
292 final Fraction b = a.multiply(2);
293 assertEquals(b, new Fraction(Integer.MAX_VALUE));
294
295 final Fraction c = new Fraction(2, Integer.MAX_VALUE);
296 final Fraction d = c.divide(2);
297 assertEquals(d, new Fraction(1, Integer.MAX_VALUE));
298 }
299
300 @Test
301 void testReciprocal() {
302 Fraction f = null;
303
304 f = new Fraction(50, 75);
305 f = f.reciprocal();
306 assertEquals(3, f.getNumerator());
307 assertEquals(2, f.getDenominator());
308
309 f = new Fraction(4, 3);
310 f = f.reciprocal();
311 assertEquals(3, f.getNumerator());
312 assertEquals(4, f.getDenominator());
313
314 f = new Fraction(-15, 47);
315 f = f.reciprocal();
316 assertEquals(-47, f.getNumerator());
317 assertEquals(15, f.getDenominator());
318
319 f = new Fraction(0, 3);
320 try {
321 f = f.reciprocal();
322 fail("expecting MathRuntimeException");
323 } catch (MathRuntimeException ex) {}
324
325
326 f = new Fraction(Integer.MAX_VALUE, 1);
327 f = f.reciprocal();
328 assertEquals(1, f.getNumerator());
329 assertEquals(Integer.MAX_VALUE, f.getDenominator());
330 }
331
332 @Test
333 void testNegate() {
334 Fraction f = null;
335
336 f = new Fraction(50, 75);
337 f = f.negate();
338 assertEquals(-2, f.getNumerator());
339 assertEquals(3, f.getDenominator());
340
341 f = new Fraction(-50, 75);
342 f = f.negate();
343 assertEquals(2, f.getNumerator());
344 assertEquals(3, f.getDenominator());
345
346
347 f = new Fraction(Integer.MAX_VALUE-1, Integer.MAX_VALUE);
348 f = f.negate();
349 assertEquals(Integer.MIN_VALUE+2, f.getNumerator());
350 assertEquals(Integer.MAX_VALUE, f.getDenominator());
351
352 f = new Fraction(Integer.MIN_VALUE, 1);
353 try {
354 f = f.negate();
355 fail("expecting MathRuntimeException");
356 } catch (MathRuntimeException ex) {}
357 }
358
359 @Test
360 void testAdd() {
361 Fraction a = new Fraction(1, 2);
362 Fraction b = new Fraction(2, 3);
363
364 customAssertFraction(1, 1, a.add(a));
365 customAssertFraction(7, 6, a.add(b));
366 customAssertFraction(7, 6, b.add(a));
367 customAssertFraction(4, 3, b.add(b));
368
369 Fraction f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
370 Fraction f2 = Fraction.ONE;
371 Fraction f = f1.add(f2);
372 assertEquals(Integer.MAX_VALUE, f.getNumerator());
373 assertEquals(1, f.getDenominator());
374 f = f1.add(1);
375 assertEquals(Integer.MAX_VALUE, f.getNumerator());
376 assertEquals(1, f.getDenominator());
377
378 f1 = new Fraction(-1, 13*13*2*2);
379 f2 = new Fraction(-2, 13*17*2);
380 f = f1.add(f2);
381 assertEquals(13*13*17*2*2, f.getDenominator());
382 assertEquals(-17 - 2*13*2, f.getNumerator());
383
384 try {
385 f.add(null);
386 fail("expecting NullArgumentException");
387 } catch (NullArgumentException ex) {}
388
389
390
391 f1 = new Fraction(1,32768*3);
392 f2 = new Fraction(1,59049);
393 f = f1.add(f2);
394 assertEquals(52451, f.getNumerator());
395 assertEquals(1934917632, f.getDenominator());
396
397 f1 = new Fraction(Integer.MIN_VALUE, 3);
398 f2 = new Fraction(1,3);
399 f = f1.add(f2);
400 assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
401 assertEquals(3, f.getDenominator());
402
403 f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
404 f2 = Fraction.ONE;
405 f = f1.add(f2);
406 assertEquals(Integer.MAX_VALUE, f.getNumerator());
407 assertEquals(1, f.getDenominator());
408
409 try {
410 f = f.add(Fraction.ONE);
411 fail("expecting MathRuntimeException but got: " + f.toString());
412 } catch (MathRuntimeException ex) {}
413
414
415 f1 = new Fraction(Integer.MIN_VALUE, 5);
416 f2 = new Fraction(-1,5);
417 try {
418 f = f1.add(f2);
419 fail("expecting MathRuntimeException but got: " + f.toString());
420 } catch (MathRuntimeException ex) {}
421
422 try {
423 f= new Fraction(-Integer.MAX_VALUE, 1);
424 f = f.add(f);
425 fail("expecting MathRuntimeException");
426 } catch (MathRuntimeException ex) {}
427
428 try {
429 f= new Fraction(-Integer.MAX_VALUE, 1);
430 f = f.add(f);
431 fail("expecting MathRuntimeException");
432 } catch (MathRuntimeException ex) {}
433
434 f1 = new Fraction(3,327680);
435 f2 = new Fraction(2,59049);
436 try {
437 f = f1.add(f2);
438 fail("expecting MathRuntimeException but got: " + f.toString());
439 } catch (MathRuntimeException ex) {}
440 }
441
442 @Test
443 void testDivide() {
444 Fraction a = new Fraction(1, 2);
445 Fraction b = new Fraction(2, 3);
446
447 customAssertFraction(1, 1, a.divide(a));
448 customAssertFraction(3, 4, a.divide(b));
449 customAssertFraction(4, 3, b.divide(a));
450 customAssertFraction(1, 1, b.divide(b));
451
452 Fraction f1 = new Fraction(3, 5);
453 Fraction f2 = Fraction.ZERO;
454 try {
455 f1.divide(f2);
456 fail("expecting MathRuntimeException");
457 } catch (MathRuntimeException ex) {}
458
459 f1 = new Fraction(0, 5);
460 f2 = new Fraction(2, 7);
461 Fraction f = f1.divide(f2);
462 assertSame(Fraction.ZERO, f);
463
464 f1 = new Fraction(2, 7);
465 f2 = Fraction.ONE;
466 f = f1.divide(f2);
467 assertEquals(2, f.getNumerator());
468 assertEquals(7, f.getDenominator());
469
470 f1 = new Fraction(1, Integer.MAX_VALUE);
471 f = f1.divide(f1);
472 assertEquals(1, f.getNumerator());
473 assertEquals(1, f.getDenominator());
474
475 f1 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
476 f2 = new Fraction(1, Integer.MAX_VALUE);
477 f = f1.divide(f2);
478 assertEquals(Integer.MIN_VALUE, f.getNumerator());
479 assertEquals(1, f.getDenominator());
480
481 try {
482 f.divide(null);
483 fail("NullArgumentException");
484 } catch (NullArgumentException ex) {}
485
486 try {
487 f1 = new Fraction(1, Integer.MAX_VALUE);
488 f = f1.divide(f1.reciprocal());
489 fail("expecting MathRuntimeException");
490 } catch (MathRuntimeException ex) {}
491 try {
492 f1 = new Fraction(1, -Integer.MAX_VALUE);
493 f = f1.divide(f1.reciprocal());
494 fail("expecting MathRuntimeException");
495 } catch (MathRuntimeException ex) {}
496
497 f1 = new Fraction(6, 35);
498 f = f1.divide(15);
499 assertEquals(2, f.getNumerator());
500 assertEquals(175, f.getDenominator());
501
502 }
503
504 @Test
505 void testMultiply() {
506 Fraction a = new Fraction(1, 2);
507 Fraction b = new Fraction(2, 3);
508
509 customAssertFraction(1, 4, a.multiply(a));
510 customAssertFraction(1, 3, a.multiply(b));
511 customAssertFraction(1, 3, b.multiply(a));
512 customAssertFraction(4, 9, b.multiply(b));
513
514 Fraction f1 = new Fraction(Integer.MAX_VALUE, 1);
515 Fraction f2 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
516 Fraction f = f1.multiply(f2);
517 assertEquals(Integer.MIN_VALUE, f.getNumerator());
518 assertEquals(1, f.getDenominator());
519
520 try {
521 f.multiply(null);
522 fail("expecting NullArgumentException");
523 } catch (NullArgumentException ex) {}
524
525 f1 = new Fraction(6, 35);
526 f = f1.multiply(15);
527 assertEquals(18, f.getNumerator());
528 assertEquals(7, f.getDenominator());
529 }
530
531 @Test
532 void testSubtract() {
533 Fraction a = new Fraction(1, 2);
534 Fraction b = new Fraction(2, 3);
535
536 customAssertFraction(0, 1, a.subtract(a));
537 customAssertFraction(-1, 6, a.subtract(b));
538 customAssertFraction(1, 6, b.subtract(a));
539 customAssertFraction(0, 1, b.subtract(b));
540
541 Fraction f = new Fraction(1,1);
542 try {
543 f.subtract(null);
544 fail("expecting NullArgumentException");
545 } catch (NullArgumentException ex) {}
546
547
548
549 Fraction f1 = new Fraction(1,32768*3);
550 Fraction f2 = new Fraction(1,59049);
551 f = f1.subtract(f2);
552 assertEquals(-13085, f.getNumerator());
553 assertEquals(1934917632, f.getDenominator());
554
555 f1 = new Fraction(Integer.MIN_VALUE, 3);
556 f2 = new Fraction(1,3).negate();
557 f = f1.subtract(f2);
558 assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
559 assertEquals(3, f.getDenominator());
560
561 f1 = new Fraction(Integer.MAX_VALUE, 1);
562 f2 = Fraction.ONE;
563 f = f1.subtract(f2);
564 assertEquals(Integer.MAX_VALUE-1, f.getNumerator());
565 assertEquals(1, f.getDenominator());
566 f = f1.subtract(1);
567 assertEquals(Integer.MAX_VALUE-1, f.getNumerator());
568 assertEquals(1, f.getDenominator());
569
570 try {
571 f1 = new Fraction(1, Integer.MAX_VALUE);
572 f2 = new Fraction(1, Integer.MAX_VALUE - 1);
573 f = f1.subtract(f2);
574 fail("expecting MathRuntimeException");
575 } catch (MathRuntimeException ex) {}
576
577
578 f1 = new Fraction(Integer.MIN_VALUE, 5);
579 f2 = new Fraction(1,5);
580 try {
581 f = f1.subtract(f2);
582 fail("expecting MathRuntimeException but got: " + f.toString());
583 } catch (MathRuntimeException ex) {}
584
585 try {
586 f= new Fraction(Integer.MIN_VALUE, 1);
587 f = f.subtract(Fraction.ONE);
588 fail("expecting MathRuntimeException");
589 } catch (MathRuntimeException ex) {}
590
591 try {
592 f= new Fraction(Integer.MAX_VALUE, 1);
593 f = f.subtract(Fraction.ONE.negate());
594 fail("expecting MathRuntimeException");
595 } catch (MathRuntimeException ex) {}
596
597 f1 = new Fraction(3,327680);
598 f2 = new Fraction(2,59049);
599 try {
600 f = f1.subtract(f2);
601 fail("expecting MathRuntimeException but got: " + f.toString());
602 } catch (MathRuntimeException ex) {}
603 }
604
605 @SuppressWarnings("unlikely-arg-type")
606 @Test
607 void testEqualsAndHashCode() {
608 Fraction zero = new Fraction(0,1);
609 Fraction nullFraction = null;
610 assertEquals(zero, zero);
611 assertNotEquals(zero, nullFraction);
612 assertNotEquals(zero, Double.valueOf(0));
613 Fraction zero2 = new Fraction(0,2);
614 assertEquals(zero, zero2);
615 assertEquals(zero.hashCode(), zero2.hashCode());
616 Fraction one = new Fraction(1,1);
617 assertFalse((one.equals(zero) ||zero.equals(one)));
618 }
619
620 @Test
621 void testGCD() {
622 Fraction first = new Fraction(1, 3);
623 Fraction second = new Fraction(2, 5);
624 Fraction third = new Fraction(3, 7);
625 Fraction gcd1 = first.gcd(second);
626 assertEquals(gcd1, Fraction.getReducedFraction(1, 15));
627 Fraction gcd2 = gcd1.gcd(third);
628 assertEquals(gcd2, Fraction.getReducedFraction(1, 105));
629
630
631 Fraction x = new Fraction(3, 7);
632 Fraction y = new Fraction(12, 22);
633 Fraction gcd = x.gcd(y);
634 assertEquals(gcd, Fraction.getReducedFraction(3, 77));
635
636 x = new Fraction(13, 6);
637 y = new Fraction(3, 4);
638 gcd = x.gcd(y);
639 assertEquals(gcd, Fraction.getReducedFraction(1, 12));
640
641 }
642
643 @Test
644 void testLCM() {
645 Fraction first = new Fraction(1, 3);
646 Fraction second = new Fraction(2, 5);
647 Fraction third = new Fraction(3, 7);
648 Fraction lcm1 = first.lcm(second);
649 assertEquals(lcm1, Fraction.getReducedFraction(2, 1));
650 Fraction lcm2 = lcm1.lcm(third);
651 assertEquals(lcm2, Fraction.getReducedFraction(6, 1));
652 }
653
654 @Test
655 void testGetReducedFraction() {
656 Fraction threeFourths = new Fraction(3, 4);
657 assertEquals(threeFourths, Fraction.getReducedFraction(6, 8));
658 assertEquals(Fraction.ZERO, Fraction.getReducedFraction(0, -1));
659 try {
660 Fraction.getReducedFraction(1, 0);
661 fail("expecting MathRuntimeException");
662 } catch (MathRuntimeException ex) {
663
664 }
665 assertEquals(-1, Fraction.getReducedFraction
666 (2, Integer.MIN_VALUE).getNumerator());
667 assertEquals(-1, Fraction.getReducedFraction
668 (1, -1).getNumerator());
669 }
670
671 @Test
672 void testNormalizedEquals() {
673 assertEquals(new Fraction(237, -3871), new Fraction(-51, 833));
674 }
675
676 @Test
677 void testToString() {
678 assertEquals("0", new Fraction(0, 3).toString());
679 assertEquals("3", new Fraction(6, 2).toString());
680 assertEquals("2 / 3", new Fraction(18, 27).toString());
681 }
682
683 @Test
684 void testSerial() {
685 Fraction[] fractions = {
686 new Fraction(3, 4), Fraction.ONE, Fraction.ZERO,
687 new Fraction(17), new Fraction(FastMath.PI, 1000),
688 new Fraction(-5, 2)
689 };
690 for (Fraction fraction : fractions) {
691 assertEquals(fraction, UnitTestUtils.serializeAndRecover(fraction));
692 }
693 }
694
695 @Test
696 void testConvergents() {
697
698
699
700
701 List<Fraction> convergents = Fraction.convergents(FastMath.PI, 20).collect(Collectors.toList());
702 assertEquals(13, convergents.size());
703 assertEquals(new Fraction( 3, 1), convergents.get( 0));
704 assertEquals(new Fraction( 22, 7), convergents.get( 1));
705 assertEquals(new Fraction( 333, 106), convergents.get( 2));
706 assertEquals(new Fraction( 355, 113), convergents.get( 3));
707 assertEquals(new Fraction( 103993, 33102), convergents.get( 4));
708 assertEquals(new Fraction( 104348, 33215), convergents.get( 5));
709 assertEquals(new Fraction( 208341, 66317), convergents.get( 6));
710 assertEquals(new Fraction( 312689, 99532), convergents.get( 7));
711 assertEquals(new Fraction( 833719, 265381), convergents.get( 8));
712 assertEquals(new Fraction( 1146408, 364913), convergents.get( 9));
713 assertEquals(new Fraction( 4272943, 1360120), convergents.get(10));
714 assertEquals(new Fraction( 5419351, 1725033), convergents.get(11));
715 assertEquals(new Fraction(80143857, 25510582), convergents.get(12));
716 }
717
718 @Test
719 void testLimitedConvergents() {
720 double value = FastMath.PI;
721 assertEquals(new Fraction( 208341, 66317),
722 Fraction.convergent(value, 7, (p, q) -> Precision.equals(p / (double) q, value, 1)).getKey());
723 }
724
725 @Test
726 void testTruncatedConvergents() {
727 final double value = FastMath.PI;
728 assertEquals(new Fraction( 355, 113),
729 Fraction.convergent(value, 20, (p, q) -> FastMath.abs(p / (double) q - value) < 1.0e-6).getKey());
730 assertEquals(new Fraction(312689, 99532),
731 Fraction.convergent(value, 20, (p, q) -> FastMath.abs(p / (double) q - value) < 1.0e-10).getKey());
732 }
733
734 }