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.math.fraction;
018    
019    import java.math.BigDecimal;
020    import java.math.BigInteger;
021    
022    import org.apache.commons.math.ConvergenceException;
023    import org.apache.commons.math.TestUtils;
024    
025    import junit.framework.TestCase;
026    
027    public class BigFractionTest extends TestCase {
028    
029        private void assertFraction(int expectedNumerator, int expectedDenominator, BigFraction actual) {
030            assertEquals(expectedNumerator, actual.getNumeratorAsInt());
031            assertEquals(expectedDenominator, actual.getDenominatorAsInt());
032        }
033    
034        private void assertFraction(long expectedNumerator, long expectedDenominator, BigFraction actual) {
035            assertEquals(expectedNumerator, actual.getNumeratorAsLong());
036            assertEquals(expectedDenominator, actual.getDenominatorAsLong());
037        }
038    
039        public void testConstructor() {
040            assertFraction(0, 1, new BigFraction(0, 1));
041            assertFraction(0, 1, new BigFraction(0l, 2l));
042            assertFraction(0, 1, new BigFraction(0, -1));
043            assertFraction(1, 2, new BigFraction(1, 2));
044            assertFraction(1, 2, new BigFraction(2, 4));
045            assertFraction(-1, 2, new BigFraction(-1, 2));
046            assertFraction(-1, 2, new BigFraction(1, -2));
047            assertFraction(-1, 2, new BigFraction(-2, 4));
048            assertFraction(-1, 2, new BigFraction(2, -4));
049            assertFraction(11, 1, new BigFraction(11));
050            assertFraction(11, 1, new BigFraction(11l));
051            assertFraction(11, 1, new BigFraction(new BigInteger("11")));
052    
053            try {
054                assertFraction(0, 1, new BigFraction(0.00000000000001, 1.0e-5, 100));
055                assertFraction(2, 5, new BigFraction(0.40000000000001, 1.0e-5, 100));
056                assertFraction(15, 1, new BigFraction(15.0000000000001, 1.0e-5, 100));
057            } catch (ConvergenceException ex) {
058                fail(ex.getMessage());
059            }
060            assertEquals(0.00000000000001, new BigFraction(0.00000000000001).doubleValue(), 0.0);
061            assertEquals(0.40000000000001, new BigFraction(0.40000000000001).doubleValue(), 0.0);
062            assertEquals(15.0000000000001, new BigFraction(15.0000000000001).doubleValue(), 0.0);
063            assertFraction(3602879701896487l, 9007199254740992l, new BigFraction(0.40000000000001));
064            assertFraction(1055531162664967l, 70368744177664l, new BigFraction(15.0000000000001));
065            try {
066                new BigFraction(null, BigInteger.ONE);
067            } catch (NullPointerException npe) {
068                // expected
069            }
070            try {
071                new BigFraction(BigInteger.ONE, null);
072            } catch (NullPointerException npe) {
073                // expected
074            }
075            try {
076                new BigFraction(BigInteger.ONE, BigInteger.ZERO);
077            } catch (ArithmeticException npe) {
078                // expected
079            }
080            try {
081                new BigFraction(2.0 * Integer.MAX_VALUE, 1.0e-5, 100000);
082            } catch (FractionConversionException fce) {
083                // expected
084            }
085        }
086    
087        public void testGoldenRatio() {
088            try {
089                // the golden ratio is notoriously a difficult number for continuous
090                // fraction
091                new BigFraction((1 + Math.sqrt(5)) / 2, 1.0e-12, 25);
092                fail("an exception should have been thrown");
093            } catch (ConvergenceException ce) {
094                // expected behavior
095            } catch (Exception e) {
096                fail("wrong exception caught");
097            }
098        }
099    
100        // MATH-179
101        public void testDoubleConstructor() throws ConvergenceException {
102            assertFraction(1, 2, new BigFraction((double) 1 / (double) 2, 1.0e-5, 100));
103            assertFraction(1, 3, new BigFraction((double) 1 / (double) 3, 1.0e-5, 100));
104            assertFraction(2, 3, new BigFraction((double) 2 / (double) 3, 1.0e-5, 100));
105            assertFraction(1, 4, new BigFraction((double) 1 / (double) 4, 1.0e-5, 100));
106            assertFraction(3, 4, new BigFraction((double) 3 / (double) 4, 1.0e-5, 100));
107            assertFraction(1, 5, new BigFraction((double) 1 / (double) 5, 1.0e-5, 100));
108            assertFraction(2, 5, new BigFraction((double) 2 / (double) 5, 1.0e-5, 100));
109            assertFraction(3, 5, new BigFraction((double) 3 / (double) 5, 1.0e-5, 100));
110            assertFraction(4, 5, new BigFraction((double) 4 / (double) 5, 1.0e-5, 100));
111            assertFraction(1, 6, new BigFraction((double) 1 / (double) 6, 1.0e-5, 100));
112            assertFraction(5, 6, new BigFraction((double) 5 / (double) 6, 1.0e-5, 100));
113            assertFraction(1, 7, new BigFraction((double) 1 / (double) 7, 1.0e-5, 100));
114            assertFraction(2, 7, new BigFraction((double) 2 / (double) 7, 1.0e-5, 100));
115            assertFraction(3, 7, new BigFraction((double) 3 / (double) 7, 1.0e-5, 100));
116            assertFraction(4, 7, new BigFraction((double) 4 / (double) 7, 1.0e-5, 100));
117            assertFraction(5, 7, new BigFraction((double) 5 / (double) 7, 1.0e-5, 100));
118            assertFraction(6, 7, new BigFraction((double) 6 / (double) 7, 1.0e-5, 100));
119            assertFraction(1, 8, new BigFraction((double) 1 / (double) 8, 1.0e-5, 100));
120            assertFraction(3, 8, new BigFraction((double) 3 / (double) 8, 1.0e-5, 100));
121            assertFraction(5, 8, new BigFraction((double) 5 / (double) 8, 1.0e-5, 100));
122            assertFraction(7, 8, new BigFraction((double) 7 / (double) 8, 1.0e-5, 100));
123            assertFraction(1, 9, new BigFraction((double) 1 / (double) 9, 1.0e-5, 100));
124            assertFraction(2, 9, new BigFraction((double) 2 / (double) 9, 1.0e-5, 100));
125            assertFraction(4, 9, new BigFraction((double) 4 / (double) 9, 1.0e-5, 100));
126            assertFraction(5, 9, new BigFraction((double) 5 / (double) 9, 1.0e-5, 100));
127            assertFraction(7, 9, new BigFraction((double) 7 / (double) 9, 1.0e-5, 100));
128            assertFraction(8, 9, new BigFraction((double) 8 / (double) 9, 1.0e-5, 100));
129            assertFraction(1, 10, new BigFraction((double) 1 / (double) 10, 1.0e-5, 100));
130            assertFraction(3, 10, new BigFraction((double) 3 / (double) 10, 1.0e-5, 100));
131            assertFraction(7, 10, new BigFraction((double) 7 / (double) 10, 1.0e-5, 100));
132            assertFraction(9, 10, new BigFraction((double) 9 / (double) 10, 1.0e-5, 100));
133            assertFraction(1, 11, new BigFraction((double) 1 / (double) 11, 1.0e-5, 100));
134            assertFraction(2, 11, new BigFraction((double) 2 / (double) 11, 1.0e-5, 100));
135            assertFraction(3, 11, new BigFraction((double) 3 / (double) 11, 1.0e-5, 100));
136            assertFraction(4, 11, new BigFraction((double) 4 / (double) 11, 1.0e-5, 100));
137            assertFraction(5, 11, new BigFraction((double) 5 / (double) 11, 1.0e-5, 100));
138            assertFraction(6, 11, new BigFraction((double) 6 / (double) 11, 1.0e-5, 100));
139            assertFraction(7, 11, new BigFraction((double) 7 / (double) 11, 1.0e-5, 100));
140            assertFraction(8, 11, new BigFraction((double) 8 / (double) 11, 1.0e-5, 100));
141            assertFraction(9, 11, new BigFraction((double) 9 / (double) 11, 1.0e-5, 100));
142            assertFraction(10, 11, new BigFraction((double) 10 / (double) 11, 1.0e-5, 100));
143        }
144    
145        // MATH-181
146        public void testDigitLimitConstructor() throws ConvergenceException {
147            assertFraction(2, 5, new BigFraction(0.4, 9));
148            assertFraction(2, 5, new BigFraction(0.4, 99));
149            assertFraction(2, 5, new BigFraction(0.4, 999));
150    
151            assertFraction(3, 5, new BigFraction(0.6152, 9));
152            assertFraction(8, 13, new BigFraction(0.6152, 99));
153            assertFraction(510, 829, new BigFraction(0.6152, 999));
154            assertFraction(769, 1250, new BigFraction(0.6152, 9999));
155        }
156    
157        public void testEpsilonLimitConstructor() throws ConvergenceException {
158            assertFraction(2, 5, new BigFraction(0.4, 1.0e-5, 100));
159    
160            assertFraction(3, 5, new BigFraction(0.6152, 0.02, 100));
161            assertFraction(8, 13, new BigFraction(0.6152, 1.0e-3, 100));
162            assertFraction(251, 408, new BigFraction(0.6152, 1.0e-4, 100));
163            assertFraction(251, 408, new BigFraction(0.6152, 1.0e-5, 100));
164            assertFraction(510, 829, new BigFraction(0.6152, 1.0e-6, 100));
165            assertFraction(769, 1250, new BigFraction(0.6152, 1.0e-7, 100));
166        }
167    
168        public void testCompareTo() {
169            BigFraction first = new BigFraction(1, 2);
170            BigFraction second = new BigFraction(1, 3);
171            BigFraction third = new BigFraction(1, 2);
172    
173            assertEquals(0, first.compareTo(first));
174            assertEquals(0, first.compareTo(third));
175            assertEquals(1, first.compareTo(second));
176            assertEquals(-1, second.compareTo(first));
177    
178            // these two values are different approximations of PI
179            // the first  one is approximately PI - 3.07e-18
180            // the second one is approximately PI + 1.936e-17
181            BigFraction pi1 = new BigFraction(1068966896, 340262731);
182            BigFraction pi2 = new BigFraction( 411557987, 131002976);
183            assertEquals(-1, pi1.compareTo(pi2));
184            assertEquals( 1, pi2.compareTo(pi1));
185            assertEquals(0.0, pi1.doubleValue() - pi2.doubleValue(), 1.0e-20);
186    
187        }
188    
189        public void testDoubleValue() {
190            BigFraction first = new BigFraction(1, 2);
191            BigFraction second = new BigFraction(1, 3);
192    
193            assertEquals(0.5, first.doubleValue(), 0.0);
194            assertEquals(1.0 / 3.0, second.doubleValue(), 0.0);
195        }
196    
197        public void testFloatValue() {
198            BigFraction first = new BigFraction(1, 2);
199            BigFraction second = new BigFraction(1, 3);
200    
201            assertEquals(0.5f, first.floatValue(), 0.0f);
202            assertEquals((float) (1.0 / 3.0), second.floatValue(), 0.0f);
203        }
204    
205        public void testIntValue() {
206            BigFraction first = new BigFraction(1, 2);
207            BigFraction second = new BigFraction(3, 2);
208    
209            assertEquals(0, first.intValue());
210            assertEquals(1, second.intValue());
211        }
212    
213        public void testLongValue() {
214            BigFraction first = new BigFraction(1, 2);
215            BigFraction second = new BigFraction(3, 2);
216    
217            assertEquals(0L, first.longValue());
218            assertEquals(1L, second.longValue());
219        }
220    
221        public void testConstructorDouble() {
222            assertFraction(1, 2, new BigFraction(0.5));
223            assertFraction(6004799503160661l, 18014398509481984l, new BigFraction(1.0 / 3.0));
224            assertFraction(6124895493223875l, 36028797018963968l, new BigFraction(17.0 / 100.0));
225            assertFraction(1784551352345559l, 562949953421312l, new BigFraction(317.0 / 100.0));
226            assertFraction(-1, 2, new BigFraction(-0.5));
227            assertFraction(-6004799503160661l, 18014398509481984l, new BigFraction(-1.0 / 3.0));
228            assertFraction(-6124895493223875l, 36028797018963968l, new BigFraction(17.0 / -100.0));
229            assertFraction(-1784551352345559l, 562949953421312l, new BigFraction(-317.0 / 100.0));
230            for (double v : new double[] { Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}) {
231                try {
232                    new BigFraction(v);
233                    fail("expected exception");
234                } catch (IllegalArgumentException iae) {
235                    // expected
236                }
237            }
238            assertEquals(1l, new BigFraction(Double.MAX_VALUE).getDenominatorAsLong());
239            assertEquals(1l, new BigFraction(Double.longBitsToDouble(0x0010000000000000L)).getNumeratorAsLong());
240            assertEquals(1l, new BigFraction(Double.MIN_VALUE).getNumeratorAsLong());
241        }
242    
243        public void testAbs() {
244            BigFraction a = new BigFraction(10, 21);
245            BigFraction b = new BigFraction(-10, 21);
246            BigFraction c = new BigFraction(10, -21);
247    
248            assertFraction(10, 21, a.abs());
249            assertFraction(10, 21, b.abs());
250            assertFraction(10, 21, c.abs());
251        }
252    
253        public void testReciprocal() {
254            BigFraction f = null;
255    
256            f = new BigFraction(50, 75);
257            f = f.reciprocal();
258            assertEquals(3, f.getNumeratorAsInt());
259            assertEquals(2, f.getDenominatorAsInt());
260    
261            f = new BigFraction(4, 3);
262            f = f.reciprocal();
263            assertEquals(3, f.getNumeratorAsInt());
264            assertEquals(4, f.getDenominatorAsInt());
265    
266            f = new BigFraction(-15, 47);
267            f = f.reciprocal();
268            assertEquals(-47, f.getNumeratorAsInt());
269            assertEquals(15, f.getDenominatorAsInt());
270    
271            f = new BigFraction(0, 3);
272            try {
273                f = f.reciprocal();
274                fail("expecting ArithmeticException");
275            } catch (ArithmeticException ex) {
276            }
277    
278            // large values
279            f = new BigFraction(Integer.MAX_VALUE, 1);
280            f = f.reciprocal();
281            assertEquals(1, f.getNumeratorAsInt());
282            assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt());
283        }
284    
285        public void testNegate() {
286            BigFraction f = null;
287    
288            f = new BigFraction(50, 75);
289            f = f.negate();
290            assertEquals(-2, f.getNumeratorAsInt());
291            assertEquals(3, f.getDenominatorAsInt());
292    
293            f = new BigFraction(-50, 75);
294            f = f.negate();
295            assertEquals(2, f.getNumeratorAsInt());
296            assertEquals(3, f.getDenominatorAsInt());
297    
298            // large values
299            f = new BigFraction(Integer.MAX_VALUE - 1, Integer.MAX_VALUE);
300            f = f.negate();
301            assertEquals(Integer.MIN_VALUE + 2, f.getNumeratorAsInt());
302            assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt());
303    
304        }
305    
306        public void testAdd() {
307            BigFraction a = new BigFraction(1, 2);
308            BigFraction b = new BigFraction(2, 3);
309    
310            assertFraction(1, 1, a.add(a));
311            assertFraction(7, 6, a.add(b));
312            assertFraction(7, 6, b.add(a));
313            assertFraction(4, 3, b.add(b));
314    
315            BigFraction f1 = new BigFraction(Integer.MAX_VALUE - 1, 1);
316            BigFraction f2 = BigFraction.ONE;
317            BigFraction f = f1.add(f2);
318            assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
319            assertEquals(1, f.getDenominatorAsInt());
320    
321            f1 = new BigFraction(-1, 13 * 13 * 2 * 2);
322            f2 = new BigFraction(-2, 13 * 17 * 2);
323            f = f1.add(f2);
324            assertEquals(13 * 13 * 17 * 2 * 2, f.getDenominatorAsInt());
325            assertEquals(-17 - 2 * 13 * 2, f.getNumeratorAsInt());
326    
327            try {
328                f.add((BigFraction) null);
329                fail("expecting NullPointerException");
330            } catch (NullPointerException ex) {
331            }
332    
333            // if this fraction is added naively, it will overflow.
334            // check that it doesn't.
335            f1 = new BigFraction(1, 32768 * 3);
336            f2 = new BigFraction(1, 59049);
337            f = f1.add(f2);
338            assertEquals(52451, f.getNumeratorAsInt());
339            assertEquals(1934917632, f.getDenominatorAsInt());
340    
341            f1 = new BigFraction(Integer.MIN_VALUE, 3);
342            f2 = new BigFraction(1, 3);
343            f = f1.add(f2);
344            assertEquals(Integer.MIN_VALUE + 1, f.getNumeratorAsInt());
345            assertEquals(3, f.getDenominatorAsInt());
346    
347            f1 = new BigFraction(Integer.MAX_VALUE - 1, 1);
348            f = f1.add(BigInteger.ONE);
349            assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
350            assertEquals(1, f.getDenominatorAsInt());
351    
352            f = f.add(BigInteger.ZERO);
353            assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
354            assertEquals(1, f.getDenominatorAsInt());
355    
356            f1 = new BigFraction(Integer.MAX_VALUE - 1, 1);
357            f = f1.add(1);
358            assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
359            assertEquals(1, f.getDenominatorAsInt());
360    
361            f = f.add(0);
362            assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
363            assertEquals(1, f.getDenominatorAsInt());
364    
365            f1 = new BigFraction(Integer.MAX_VALUE - 1, 1);
366            f = f1.add(1l);
367            assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
368            assertEquals(1, f.getDenominatorAsInt());
369    
370            f = f.add(0l);
371            assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
372            assertEquals(1, f.getDenominatorAsInt());
373    
374        }
375    
376        public void testDivide() {
377            BigFraction a = new BigFraction(1, 2);
378            BigFraction b = new BigFraction(2, 3);
379    
380            assertFraction(1, 1, a.divide(a));
381            assertFraction(3, 4, a.divide(b));
382            assertFraction(4, 3, b.divide(a));
383            assertFraction(1, 1, b.divide(b));
384    
385            BigFraction f1 = new BigFraction(3, 5);
386            BigFraction f2 = BigFraction.ZERO;
387            try {
388                f1.divide(f2);
389                fail("expecting ArithmeticException");
390            } catch (ArithmeticException ex) {
391            }
392    
393            f1 = new BigFraction(0, 5);
394            f2 = new BigFraction(2, 7);
395            BigFraction f = f1.divide(f2);
396            assertSame(BigFraction.ZERO, f);
397    
398            f1 = new BigFraction(2, 7);
399            f2 = BigFraction.ONE;
400            f = f1.divide(f2);
401            assertEquals(2, f.getNumeratorAsInt());
402            assertEquals(7, f.getDenominatorAsInt());
403    
404            f1 = new BigFraction(1, Integer.MAX_VALUE);
405            f = f1.divide(f1);
406            assertEquals(1, f.getNumeratorAsInt());
407            assertEquals(1, f.getDenominatorAsInt());
408    
409            f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
410            f2 = new BigFraction(1, Integer.MAX_VALUE);
411            f = f1.divide(f2);
412            assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt());
413            assertEquals(1, f.getDenominatorAsInt());
414    
415            try {
416                f.divide((BigFraction) null);
417                fail("expecting NullPointerException");
418            } catch (NullPointerException ex) {
419            }
420    
421            f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
422            f = f1.divide(BigInteger.valueOf(Integer.MIN_VALUE));
423            assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt());
424            assertEquals(1, f.getNumeratorAsInt());
425    
426            f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
427            f = f1.divide(Integer.MIN_VALUE);
428            assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt());
429            assertEquals(1, f.getNumeratorAsInt());
430    
431            f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
432            f = f1.divide((long) Integer.MIN_VALUE);
433            assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt());
434            assertEquals(1, f.getNumeratorAsInt());
435    
436        }
437    
438        public void testMultiply() {
439            BigFraction a = new BigFraction(1, 2);
440            BigFraction b = new BigFraction(2, 3);
441    
442            assertFraction(1, 4, a.multiply(a));
443            assertFraction(1, 3, a.multiply(b));
444            assertFraction(1, 3, b.multiply(a));
445            assertFraction(4, 9, b.multiply(b));
446    
447            BigFraction f1 = new BigFraction(Integer.MAX_VALUE, 1);
448            BigFraction f2 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
449            BigFraction f = f1.multiply(f2);
450            assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt());
451            assertEquals(1, f.getDenominatorAsInt());
452    
453            f = f2.multiply(Integer.MAX_VALUE);
454            assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt());
455            assertEquals(1, f.getDenominatorAsInt());
456    
457            f = f2.multiply((long) Integer.MAX_VALUE);
458            assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt());
459            assertEquals(1, f.getDenominatorAsInt());
460    
461            try {
462                f.multiply((BigFraction) null);
463                fail("expecting NullPointerException");
464            } catch (NullPointerException ex) {
465            }
466    
467        }
468    
469        public void testSubtract() {
470            BigFraction a = new BigFraction(1, 2);
471            BigFraction b = new BigFraction(2, 3);
472    
473            assertFraction(0, 1, a.subtract(a));
474            assertFraction(-1, 6, a.subtract(b));
475            assertFraction(1, 6, b.subtract(a));
476            assertFraction(0, 1, b.subtract(b));
477    
478            BigFraction f = new BigFraction(1, 1);
479            try {
480                f.subtract((BigFraction) null);
481                fail("expecting NullPointerException");
482            } catch (NullPointerException ex) {
483            }
484    
485            // if this fraction is subtracted naively, it will overflow.
486            // check that it doesn't.
487            BigFraction f1 = new BigFraction(1, 32768 * 3);
488            BigFraction f2 = new BigFraction(1, 59049);
489            f = f1.subtract(f2);
490            assertEquals(-13085, f.getNumeratorAsInt());
491            assertEquals(1934917632, f.getDenominatorAsInt());
492    
493            f1 = new BigFraction(Integer.MIN_VALUE, 3);
494            f2 = new BigFraction(1, 3).negate();
495            f = f1.subtract(f2);
496            assertEquals(Integer.MIN_VALUE + 1, f.getNumeratorAsInt());
497            assertEquals(3, f.getDenominatorAsInt());
498    
499            f1 = new BigFraction(Integer.MAX_VALUE, 1);
500            f2 = BigFraction.ONE;
501            f = f1.subtract(f2);
502            assertEquals(Integer.MAX_VALUE - 1, f.getNumeratorAsInt());
503            assertEquals(1, f.getDenominatorAsInt());
504    
505        }
506    
507        public void testBigDecimalValue() {
508            assertEquals(new BigDecimal(0.5), new BigFraction(1, 2).bigDecimalValue());
509            assertEquals(new BigDecimal("0.0003"), new BigFraction(3, 10000).bigDecimalValue());
510            assertEquals(new BigDecimal("0"), new BigFraction(1, 3).bigDecimalValue(BigDecimal.ROUND_DOWN));
511            assertEquals(new BigDecimal("0.333"), new BigFraction(1, 3).bigDecimalValue(3, BigDecimal.ROUND_DOWN));
512        }
513    
514        public void testEqualsAndHashCode() {
515            BigFraction zero = new BigFraction(0, 1);
516            BigFraction nullFraction = null;
517            assertTrue(zero.equals(zero));
518            assertFalse(zero.equals(nullFraction));
519            assertFalse(zero.equals(Double.valueOf(0)));
520            BigFraction zero2 = new BigFraction(0, 2);
521            assertTrue(zero.equals(zero2));
522            assertEquals(zero.hashCode(), zero2.hashCode());
523            BigFraction one = new BigFraction(1, 1);
524            assertFalse((one.equals(zero) || zero.equals(one)));
525            assertTrue(one.equals(BigFraction.ONE));
526        }
527    
528        public void testGetReducedFraction() {
529            BigFraction threeFourths = new BigFraction(3, 4);
530            assertTrue(threeFourths.equals(BigFraction.getReducedFraction(6, 8)));
531            assertTrue(BigFraction.ZERO.equals(BigFraction.getReducedFraction(0, -1)));
532            try {
533                BigFraction.getReducedFraction(1, 0);
534                fail("expecting ArithmeticException");
535            } catch (ArithmeticException ex) {
536                // expected
537            }
538            assertEquals(BigFraction.getReducedFraction(2, Integer.MIN_VALUE).getNumeratorAsInt(), -1);
539            assertEquals(BigFraction.getReducedFraction(1, -1).getNumeratorAsInt(), -1);
540        }
541    
542        public void testPow() {
543            assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(13));
544            assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(13l));
545            assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(BigInteger.valueOf(13l)));
546            assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(0));
547            assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(0l));
548            assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(BigInteger.valueOf(0l)));
549            assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(-13));
550            assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(-13l));
551            assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(BigInteger.valueOf(-13l)));
552        }
553    
554        public void testSerial() throws FractionConversionException {
555            BigFraction[] fractions = {
556                new BigFraction(3, 4), BigFraction.ONE, BigFraction.ZERO,
557                new BigFraction(17), new BigFraction(Math.PI, 1000),
558                new BigFraction(-5, 2)
559            };
560            for (BigFraction fraction : fractions) {
561                assertEquals(fraction, TestUtils.serializeAndRecover(fraction));
562            }
563        }
564    
565    }