001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.math3.fraction;
018    
019    import org.apache.commons.math3.exception.ConvergenceException;
020    import org.apache.commons.math3.exception.MathIllegalArgumentException;
021    import org.apache.commons.math3.exception.MathArithmeticException;
022    import org.apache.commons.math3.TestUtils;
023    import org.apache.commons.math3.util.FastMath;
024    import org.junit.Assert;
025    import org.junit.Test;
026    
027    
028    /**
029     * @version $Id: FractionTest.java 1368253 2012-08-01 21:24:27Z tn $
030     */
031    public class FractionTest {
032    
033        private void assertFraction(int expectedNumerator, int expectedDenominator, Fraction actual) {
034            Assert.assertEquals(expectedNumerator, actual.getNumerator());
035            Assert.assertEquals(expectedDenominator, actual.getDenominator());
036        }
037    
038        @Test
039        public void testConstructor() {
040            assertFraction(0, 1, new Fraction(0, 1));
041            assertFraction(0, 1, new Fraction(0, 2));
042            assertFraction(0, 1, new Fraction(0, -1));
043            assertFraction(1, 2, new Fraction(1, 2));
044            assertFraction(1, 2, new Fraction(2, 4));
045            assertFraction(-1, 2, new Fraction(-1, 2));
046            assertFraction(-1, 2, new Fraction(1, -2));
047            assertFraction(-1, 2, new Fraction(-2, 4));
048            assertFraction(-1, 2, new Fraction(2, -4));
049    
050            // overflow
051            try {
052                new Fraction(Integer.MIN_VALUE, -1);
053                Assert.fail();
054            } catch (MathArithmeticException ex) {
055                // success
056            }
057            try {
058                new Fraction(1, Integer.MIN_VALUE);
059                Assert.fail();
060            } catch (MathArithmeticException ex) {
061                // success
062            }
063    
064            assertFraction(0, 1, new Fraction(0.00000000000001));
065            assertFraction(2, 5, new Fraction(0.40000000000001));
066            assertFraction(15, 1, new Fraction(15.0000000000001));
067        }
068    
069        @Test(expected=ConvergenceException.class)
070        public void testGoldenRatio() {
071            // the golden ratio is notoriously a difficult number for continuous fraction
072            new Fraction((1 + FastMath.sqrt(5)) / 2, 1.0e-12, 25);
073        }
074    
075        // MATH-179
076        @Test
077        public void testDoubleConstructor() throws ConvergenceException  {
078            assertFraction(1, 2, new Fraction((double)1 / (double)2));
079            assertFraction(1, 3, new Fraction((double)1 / (double)3));
080            assertFraction(2, 3, new Fraction((double)2 / (double)3));
081            assertFraction(1, 4, new Fraction((double)1 / (double)4));
082            assertFraction(3, 4, new Fraction((double)3 / (double)4));
083            assertFraction(1, 5, new Fraction((double)1 / (double)5));
084            assertFraction(2, 5, new Fraction((double)2 / (double)5));
085            assertFraction(3, 5, new Fraction((double)3 / (double)5));
086            assertFraction(4, 5, new Fraction((double)4 / (double)5));
087            assertFraction(1, 6, new Fraction((double)1 / (double)6));
088            assertFraction(5, 6, new Fraction((double)5 / (double)6));
089            assertFraction(1, 7, new Fraction((double)1 / (double)7));
090            assertFraction(2, 7, new Fraction((double)2 / (double)7));
091            assertFraction(3, 7, new Fraction((double)3 / (double)7));
092            assertFraction(4, 7, new Fraction((double)4 / (double)7));
093            assertFraction(5, 7, new Fraction((double)5 / (double)7));
094            assertFraction(6, 7, new Fraction((double)6 / (double)7));
095            assertFraction(1, 8, new Fraction((double)1 / (double)8));
096            assertFraction(3, 8, new Fraction((double)3 / (double)8));
097            assertFraction(5, 8, new Fraction((double)5 / (double)8));
098            assertFraction(7, 8, new Fraction((double)7 / (double)8));
099            assertFraction(1, 9, new Fraction((double)1 / (double)9));
100            assertFraction(2, 9, new Fraction((double)2 / (double)9));
101            assertFraction(4, 9, new Fraction((double)4 / (double)9));
102            assertFraction(5, 9, new Fraction((double)5 / (double)9));
103            assertFraction(7, 9, new Fraction((double)7 / (double)9));
104            assertFraction(8, 9, new Fraction((double)8 / (double)9));
105            assertFraction(1, 10, new Fraction((double)1 / (double)10));
106            assertFraction(3, 10, new Fraction((double)3 / (double)10));
107            assertFraction(7, 10, new Fraction((double)7 / (double)10));
108            assertFraction(9, 10, new Fraction((double)9 / (double)10));
109            assertFraction(1, 11, new Fraction((double)1 / (double)11));
110            assertFraction(2, 11, new Fraction((double)2 / (double)11));
111            assertFraction(3, 11, new Fraction((double)3 / (double)11));
112            assertFraction(4, 11, new Fraction((double)4 / (double)11));
113            assertFraction(5, 11, new Fraction((double)5 / (double)11));
114            assertFraction(6, 11, new Fraction((double)6 / (double)11));
115            assertFraction(7, 11, new Fraction((double)7 / (double)11));
116            assertFraction(8, 11, new Fraction((double)8 / (double)11));
117            assertFraction(9, 11, new Fraction((double)9 / (double)11));
118            assertFraction(10, 11, new Fraction((double)10 / (double)11));
119        }
120    
121        // MATH-181
122        @Test
123        public void testDigitLimitConstructor() throws ConvergenceException  {
124            assertFraction(2, 5, new Fraction(0.4,   9));
125            assertFraction(2, 5, new Fraction(0.4,  99));
126            assertFraction(2, 5, new Fraction(0.4, 999));
127    
128            assertFraction(3, 5,      new Fraction(0.6152,    9));
129            assertFraction(8, 13,     new Fraction(0.6152,   99));
130            assertFraction(510, 829,  new Fraction(0.6152,  999));
131            assertFraction(769, 1250, new Fraction(0.6152, 9999));
132        }
133    
134        @Test
135        public void testIntegerOverflow() {
136            checkIntegerOverflow(0.75000000001455192);
137            checkIntegerOverflow(1.0e10);
138            checkIntegerOverflow(-1.0e10);
139            checkIntegerOverflow(-43979.60679604749);
140        }
141    
142        private void checkIntegerOverflow(double a) {
143            try {
144                new Fraction(a, 1.0e-12, 1000);
145                Assert.fail("an exception should have been thrown");
146            } catch (ConvergenceException ce) {
147                // expected behavior
148            }
149        }
150    
151        @Test
152        public void testEpsilonLimitConstructor() throws ConvergenceException  {
153            assertFraction(2, 5, new Fraction(0.4, 1.0e-5, 100));
154    
155            assertFraction(3, 5,      new Fraction(0.6152, 0.02, 100));
156            assertFraction(8, 13,     new Fraction(0.6152, 1.0e-3, 100));
157            assertFraction(251, 408,  new Fraction(0.6152, 1.0e-4, 100));
158            assertFraction(251, 408,  new Fraction(0.6152, 1.0e-5, 100));
159            assertFraction(510, 829,  new Fraction(0.6152, 1.0e-6, 100));
160            assertFraction(769, 1250, new Fraction(0.6152, 1.0e-7, 100));
161        }
162    
163        @Test
164        public void testCompareTo() {
165            Fraction first = new Fraction(1, 2);
166            Fraction second = new Fraction(1, 3);
167            Fraction third = new Fraction(1, 2);
168    
169            Assert.assertEquals(0, first.compareTo(first));
170            Assert.assertEquals(0, first.compareTo(third));
171            Assert.assertEquals(1, first.compareTo(second));
172            Assert.assertEquals(-1, second.compareTo(first));
173    
174            // these two values are different approximations of PI
175            // the first  one is approximately PI - 3.07e-18
176            // the second one is approximately PI + 1.936e-17
177            Fraction pi1 = new Fraction(1068966896, 340262731);
178            Fraction pi2 = new Fraction( 411557987, 131002976);
179            Assert.assertEquals(-1, pi1.compareTo(pi2));
180            Assert.assertEquals( 1, pi2.compareTo(pi1));
181            Assert.assertEquals(0.0, pi1.doubleValue() - pi2.doubleValue(), 1.0e-20);
182        }
183    
184        @Test
185        public void testDoubleValue() {
186            Fraction first = new Fraction(1, 2);
187            Fraction second = new Fraction(1, 3);
188    
189            Assert.assertEquals(0.5, first.doubleValue(), 0.0);
190            Assert.assertEquals(1.0 / 3.0, second.doubleValue(), 0.0);
191        }
192    
193        @Test
194        public void testFloatValue() {
195            Fraction first = new Fraction(1, 2);
196            Fraction second = new Fraction(1, 3);
197    
198            Assert.assertEquals(0.5f, first.floatValue(), 0.0f);
199            Assert.assertEquals((float)(1.0 / 3.0), second.floatValue(), 0.0f);
200        }
201    
202        @Test
203        public void testIntValue() {
204            Fraction first = new Fraction(1, 2);
205            Fraction second = new Fraction(3, 2);
206    
207            Assert.assertEquals(0, first.intValue());
208            Assert.assertEquals(1, second.intValue());
209        }
210    
211        @Test
212        public void testLongValue() {
213            Fraction first = new Fraction(1, 2);
214            Fraction second = new Fraction(3, 2);
215    
216            Assert.assertEquals(0L, first.longValue());
217            Assert.assertEquals(1L, second.longValue());
218        }
219    
220        @Test
221        public void testConstructorDouble() {
222            assertFraction(1, 2, new Fraction(0.5));
223            assertFraction(1, 3, new Fraction(1.0 / 3.0));
224            assertFraction(17, 100, new Fraction(17.0 / 100.0));
225            assertFraction(317, 100, new Fraction(317.0 / 100.0));
226            assertFraction(-1, 2, new Fraction(-0.5));
227            assertFraction(-1, 3, new Fraction(-1.0 / 3.0));
228            assertFraction(-17, 100, new Fraction(17.0 / -100.0));
229            assertFraction(-317, 100, new Fraction(-317.0 / 100.0));
230        }
231    
232        @Test
233        public void testAbs() {
234            Fraction a = new Fraction(10, 21);
235            Fraction b = new Fraction(-10, 21);
236            Fraction c = new Fraction(10, -21);
237    
238            assertFraction(10, 21, a.abs());
239            assertFraction(10, 21, b.abs());
240            assertFraction(10, 21, c.abs());
241        }
242    
243        @Test
244        public void testPercentage() {
245            Assert.assertEquals(50.0, new Fraction(1, 2).percentageValue(), 1.0e-15);
246        }
247    
248        @Test
249        public void testMath835() {
250            final int numer = Integer.MAX_VALUE / 99;
251            final int denom = 1;
252            final double percentage = 100 * ((double) numer) / denom;
253            final Fraction frac = new Fraction(numer, denom);
254            // With the implementation that preceded the fix suggested in MATH-835,
255            // this test was failing, due to overflow.
256            Assert.assertEquals(percentage, frac.percentageValue(), Math.ulp(percentage));
257        }
258    
259        @Test
260        public void testReciprocal() {
261            Fraction f = null;
262    
263            f = new Fraction(50, 75);
264            f = f.reciprocal();
265            Assert.assertEquals(3, f.getNumerator());
266            Assert.assertEquals(2, f.getDenominator());
267    
268            f = new Fraction(4, 3);
269            f = f.reciprocal();
270            Assert.assertEquals(3, f.getNumerator());
271            Assert.assertEquals(4, f.getDenominator());
272    
273            f = new Fraction(-15, 47);
274            f = f.reciprocal();
275            Assert.assertEquals(-47, f.getNumerator());
276            Assert.assertEquals(15, f.getDenominator());
277    
278            f = new Fraction(0, 3);
279            try {
280                f = f.reciprocal();
281                Assert.fail("expecting MathArithmeticException");
282            } catch (MathArithmeticException ex) {}
283    
284            // large values
285            f = new Fraction(Integer.MAX_VALUE, 1);
286            f = f.reciprocal();
287            Assert.assertEquals(1, f.getNumerator());
288            Assert.assertEquals(Integer.MAX_VALUE, f.getDenominator());
289        }
290    
291        @Test
292        public void testNegate() {
293            Fraction f = null;
294    
295            f = new Fraction(50, 75);
296            f = f.negate();
297            Assert.assertEquals(-2, f.getNumerator());
298            Assert.assertEquals(3, f.getDenominator());
299    
300            f = new Fraction(-50, 75);
301            f = f.negate();
302            Assert.assertEquals(2, f.getNumerator());
303            Assert.assertEquals(3, f.getDenominator());
304    
305            // large values
306            f = new Fraction(Integer.MAX_VALUE-1, Integer.MAX_VALUE);
307            f = f.negate();
308            Assert.assertEquals(Integer.MIN_VALUE+2, f.getNumerator());
309            Assert.assertEquals(Integer.MAX_VALUE, f.getDenominator());
310    
311            f = new Fraction(Integer.MIN_VALUE, 1);
312            try {
313                f = f.negate();
314                Assert.fail("expecting MathArithmeticException");
315            } catch (MathArithmeticException ex) {}
316        }
317    
318        @Test
319        public void testAdd() {
320            Fraction a = new Fraction(1, 2);
321            Fraction b = new Fraction(2, 3);
322    
323            assertFraction(1, 1, a.add(a));
324            assertFraction(7, 6, a.add(b));
325            assertFraction(7, 6, b.add(a));
326            assertFraction(4, 3, b.add(b));
327    
328            Fraction f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
329            Fraction f2 = Fraction.ONE;
330            Fraction f = f1.add(f2);
331            Assert.assertEquals(Integer.MAX_VALUE, f.getNumerator());
332            Assert.assertEquals(1, f.getDenominator());
333            f = f1.add(1);
334            Assert.assertEquals(Integer.MAX_VALUE, f.getNumerator());
335            Assert.assertEquals(1, f.getDenominator());
336    
337            f1 = new Fraction(-1, 13*13*2*2);
338            f2 = new Fraction(-2, 13*17*2);
339            f = f1.add(f2);
340            Assert.assertEquals(13*13*17*2*2, f.getDenominator());
341            Assert.assertEquals(-17 - 2*13*2, f.getNumerator());
342    
343            try {
344                f.add(null);
345                Assert.fail("expecting MathIllegalArgumentException");
346            } catch (MathIllegalArgumentException ex) {}
347    
348            // if this fraction is added naively, it will overflow.
349            // check that it doesn't.
350            f1 = new Fraction(1,32768*3);
351            f2 = new Fraction(1,59049);
352            f = f1.add(f2);
353            Assert.assertEquals(52451, f.getNumerator());
354            Assert.assertEquals(1934917632, f.getDenominator());
355    
356            f1 = new Fraction(Integer.MIN_VALUE, 3);
357            f2 = new Fraction(1,3);
358            f = f1.add(f2);
359            Assert.assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
360            Assert.assertEquals(3, f.getDenominator());
361    
362            f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
363            f2 = Fraction.ONE;
364            f = f1.add(f2);
365            Assert.assertEquals(Integer.MAX_VALUE, f.getNumerator());
366            Assert.assertEquals(1, f.getDenominator());
367    
368            try {
369                f = f.add(Fraction.ONE); // should overflow
370                Assert.fail("expecting MathArithmeticException but got: " + f.toString());
371            } catch (MathArithmeticException ex) {}
372    
373            // denominator should not be a multiple of 2 or 3 to trigger overflow
374            f1 = new Fraction(Integer.MIN_VALUE, 5);
375            f2 = new Fraction(-1,5);
376            try {
377                f = f1.add(f2); // should overflow
378                Assert.fail("expecting MathArithmeticException but got: " + f.toString());
379            } catch (MathArithmeticException ex) {}
380    
381            try {
382                f= new Fraction(-Integer.MAX_VALUE, 1);
383                f = f.add(f);
384                Assert.fail("expecting MathArithmeticException");
385            } catch (MathArithmeticException ex) {}
386    
387            try {
388                f= new Fraction(-Integer.MAX_VALUE, 1);
389                f = f.add(f);
390                Assert.fail("expecting MathArithmeticException");
391            } catch (MathArithmeticException ex) {}
392    
393            f1 = new Fraction(3,327680);
394            f2 = new Fraction(2,59049);
395            try {
396                f = f1.add(f2); // should overflow
397                Assert.fail("expecting MathArithmeticException but got: " + f.toString());
398            } catch (MathArithmeticException ex) {}
399        }
400    
401        @Test
402        public void testDivide() {
403            Fraction a = new Fraction(1, 2);
404            Fraction b = new Fraction(2, 3);
405    
406            assertFraction(1, 1, a.divide(a));
407            assertFraction(3, 4, a.divide(b));
408            assertFraction(4, 3, b.divide(a));
409            assertFraction(1, 1, b.divide(b));
410    
411            Fraction f1 = new Fraction(3, 5);
412            Fraction f2 = Fraction.ZERO;
413            try {
414                f1.divide(f2);
415                Assert.fail("expecting MathArithmeticException");
416            } catch (MathArithmeticException ex) {}
417    
418            f1 = new Fraction(0, 5);
419            f2 = new Fraction(2, 7);
420            Fraction f = f1.divide(f2);
421            Assert.assertSame(Fraction.ZERO, f);
422    
423            f1 = new Fraction(2, 7);
424            f2 = Fraction.ONE;
425            f = f1.divide(f2);
426            Assert.assertEquals(2, f.getNumerator());
427            Assert.assertEquals(7, f.getDenominator());
428    
429            f1 = new Fraction(1, Integer.MAX_VALUE);
430            f = f1.divide(f1);
431            Assert.assertEquals(1, f.getNumerator());
432            Assert.assertEquals(1, f.getDenominator());
433    
434            f1 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
435            f2 = new Fraction(1, Integer.MAX_VALUE);
436            f = f1.divide(f2);
437            Assert.assertEquals(Integer.MIN_VALUE, f.getNumerator());
438            Assert.assertEquals(1, f.getDenominator());
439    
440            try {
441                f.divide(null);
442                Assert.fail("MathIllegalArgumentException");
443            } catch (MathIllegalArgumentException ex) {}
444    
445            try {
446                f1 = new Fraction(1, Integer.MAX_VALUE);
447                f = f1.divide(f1.reciprocal());  // should overflow
448                Assert.fail("expecting MathArithmeticException");
449            } catch (MathArithmeticException ex) {}
450            try {
451                f1 = new Fraction(1, -Integer.MAX_VALUE);
452                f = f1.divide(f1.reciprocal());  // should overflow
453                Assert.fail("expecting MathArithmeticException");
454            } catch (MathArithmeticException ex) {}
455    
456            f1 = new Fraction(6, 35);
457            f  = f1.divide(15);
458            Assert.assertEquals(2, f.getNumerator());
459            Assert.assertEquals(175, f.getDenominator());
460    
461        }
462    
463        @Test
464        public void testMultiply() {
465            Fraction a = new Fraction(1, 2);
466            Fraction b = new Fraction(2, 3);
467    
468            assertFraction(1, 4, a.multiply(a));
469            assertFraction(1, 3, a.multiply(b));
470            assertFraction(1, 3, b.multiply(a));
471            assertFraction(4, 9, b.multiply(b));
472    
473            Fraction f1 = new Fraction(Integer.MAX_VALUE, 1);
474            Fraction f2 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
475            Fraction f = f1.multiply(f2);
476            Assert.assertEquals(Integer.MIN_VALUE, f.getNumerator());
477            Assert.assertEquals(1, f.getDenominator());
478    
479            try {
480                f.multiply(null);
481                Assert.fail("expecting MathIllegalArgumentException");
482            } catch (MathIllegalArgumentException ex) {}
483    
484            f1 = new Fraction(6, 35);
485            f  = f1.multiply(15);
486            Assert.assertEquals(18, f.getNumerator());
487            Assert.assertEquals(7, f.getDenominator());
488        }
489    
490        @Test
491        public void testSubtract() {
492            Fraction a = new Fraction(1, 2);
493            Fraction b = new Fraction(2, 3);
494    
495            assertFraction(0, 1, a.subtract(a));
496            assertFraction(-1, 6, a.subtract(b));
497            assertFraction(1, 6, b.subtract(a));
498            assertFraction(0, 1, b.subtract(b));
499    
500            Fraction f = new Fraction(1,1);
501            try {
502                f.subtract(null);
503                Assert.fail("expecting MathIllegalArgumentException");
504            } catch (MathIllegalArgumentException ex) {}
505    
506            // if this fraction is subtracted naively, it will overflow.
507            // check that it doesn't.
508            Fraction f1 = new Fraction(1,32768*3);
509            Fraction f2 = new Fraction(1,59049);
510            f = f1.subtract(f2);
511            Assert.assertEquals(-13085, f.getNumerator());
512            Assert.assertEquals(1934917632, f.getDenominator());
513    
514            f1 = new Fraction(Integer.MIN_VALUE, 3);
515            f2 = new Fraction(1,3).negate();
516            f = f1.subtract(f2);
517            Assert.assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
518            Assert.assertEquals(3, f.getDenominator());
519    
520            f1 = new Fraction(Integer.MAX_VALUE, 1);
521            f2 = Fraction.ONE;
522            f = f1.subtract(f2);
523            Assert.assertEquals(Integer.MAX_VALUE-1, f.getNumerator());
524            Assert.assertEquals(1, f.getDenominator());
525            f = f1.subtract(1);
526            Assert.assertEquals(Integer.MAX_VALUE-1, f.getNumerator());
527            Assert.assertEquals(1, f.getDenominator());
528    
529            try {
530                f1 = new Fraction(1, Integer.MAX_VALUE);
531                f2 = new Fraction(1, Integer.MAX_VALUE - 1);
532                f = f1.subtract(f2);
533                Assert.fail("expecting MathArithmeticException");  //should overflow
534            } catch (MathArithmeticException ex) {}
535    
536            // denominator should not be a multiple of 2 or 3 to trigger overflow
537            f1 = new Fraction(Integer.MIN_VALUE, 5);
538            f2 = new Fraction(1,5);
539            try {
540                f = f1.subtract(f2); // should overflow
541                Assert.fail("expecting MathArithmeticException but got: " + f.toString());
542            } catch (MathArithmeticException ex) {}
543    
544            try {
545                f= new Fraction(Integer.MIN_VALUE, 1);
546                f = f.subtract(Fraction.ONE);
547                Assert.fail("expecting MathArithmeticException");
548            } catch (MathArithmeticException ex) {}
549    
550            try {
551                f= new Fraction(Integer.MAX_VALUE, 1);
552                f = f.subtract(Fraction.ONE.negate());
553                Assert.fail("expecting MathArithmeticException");
554            } catch (MathArithmeticException ex) {}
555    
556            f1 = new Fraction(3,327680);
557            f2 = new Fraction(2,59049);
558            try {
559                f = f1.subtract(f2); // should overflow
560                Assert.fail("expecting MathArithmeticException but got: " + f.toString());
561            } catch (MathArithmeticException ex) {}
562        }
563    
564        @Test
565        public void testEqualsAndHashCode() {
566            Fraction zero  = new Fraction(0,1);
567            Fraction nullFraction = null;
568            Assert.assertTrue( zero.equals(zero));
569            Assert.assertFalse(zero.equals(nullFraction));
570            Assert.assertFalse(zero.equals(Double.valueOf(0)));
571            Fraction zero2 = new Fraction(0,2);
572            Assert.assertTrue(zero.equals(zero2));
573            Assert.assertEquals(zero.hashCode(), zero2.hashCode());
574            Fraction one = new Fraction(1,1);
575            Assert.assertFalse((one.equals(zero) ||zero.equals(one)));
576        }
577    
578        @Test
579        public void testGetReducedFraction() {
580            Fraction threeFourths = new Fraction(3, 4);
581            Assert.assertTrue(threeFourths.equals(Fraction.getReducedFraction(6, 8)));
582            Assert.assertTrue(Fraction.ZERO.equals(Fraction.getReducedFraction(0, -1)));
583            try {
584                Fraction.getReducedFraction(1, 0);
585                Assert.fail("expecting MathArithmeticException");
586            } catch (MathArithmeticException ex) {
587                // expected
588            }
589            Assert.assertEquals(Fraction.getReducedFraction
590                    (2, Integer.MIN_VALUE).getNumerator(),-1);
591            Assert.assertEquals(Fraction.getReducedFraction
592                    (1, -1).getNumerator(), -1);
593        }
594    
595        @Test
596        public void testToString() {
597            Assert.assertEquals("0", new Fraction(0, 3).toString());
598            Assert.assertEquals("3", new Fraction(6, 2).toString());
599            Assert.assertEquals("2 / 3", new Fraction(18, 27).toString());
600        }
601    
602        @Test
603        public void testSerial() throws FractionConversionException {
604            Fraction[] fractions = {
605                new Fraction(3, 4), Fraction.ONE, Fraction.ZERO,
606                new Fraction(17), new Fraction(FastMath.PI, 1000),
607                new Fraction(-5, 2)
608            };
609            for (Fraction fraction : fractions) {
610                Assert.assertEquals(fraction, TestUtils.serializeAndRecover(fraction));
611            }
612        }
613    
614    }