1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math.fraction;
18  
19  import java.math.BigDecimal;
20  import java.math.BigInteger;
21  
22  import org.apache.commons.math.ConvergenceException;
23  import org.apache.commons.math.TestUtils;
24  
25  import junit.framework.TestCase;
26  
27  public class BigFractionTest extends TestCase {
28  
29      private void assertFraction(int expectedNumerator, int expectedDenominator, BigFraction actual) {
30          assertEquals(expectedNumerator, actual.getNumeratorAsInt());
31          assertEquals(expectedDenominator, actual.getDenominatorAsInt());
32      }
33  
34      private void assertFraction(long expectedNumerator, long expectedDenominator, BigFraction actual) {
35          assertEquals(expectedNumerator, actual.getNumeratorAsLong());
36          assertEquals(expectedDenominator, actual.getDenominatorAsLong());
37      }
38  
39      public void testConstructor() {
40          assertFraction(0, 1, new BigFraction(0, 1));
41          assertFraction(0, 1, new BigFraction(0l, 2l));
42          assertFraction(0, 1, new BigFraction(0, -1));
43          assertFraction(1, 2, new BigFraction(1, 2));
44          assertFraction(1, 2, new BigFraction(2, 4));
45          assertFraction(-1, 2, new BigFraction(-1, 2));
46          assertFraction(-1, 2, new BigFraction(1, -2));
47          assertFraction(-1, 2, new BigFraction(-2, 4));
48          assertFraction(-1, 2, new BigFraction(2, -4));
49          assertFraction(11, 1, new BigFraction(11));
50          assertFraction(11, 1, new BigFraction(11l));
51          assertFraction(11, 1, new BigFraction(new BigInteger("11")));
52  
53          try {
54              assertFraction(0, 1, new BigFraction(0.00000000000001, 1.0e-5, 100));
55              assertFraction(2, 5, new BigFraction(0.40000000000001, 1.0e-5, 100));
56              assertFraction(15, 1, new BigFraction(15.0000000000001, 1.0e-5, 100));
57          } catch (ConvergenceException ex) {
58              fail(ex.getMessage());
59          }
60          assertEquals(0.00000000000001, new BigFraction(0.00000000000001).doubleValue(), 0.0);
61          assertEquals(0.40000000000001, new BigFraction(0.40000000000001).doubleValue(), 0.0);
62          assertEquals(15.0000000000001, new BigFraction(15.0000000000001).doubleValue(), 0.0);
63          assertFraction(3602879701896487l, 9007199254740992l, new BigFraction(0.40000000000001));
64          assertFraction(1055531162664967l, 70368744177664l, new BigFraction(15.0000000000001));
65          try {
66              new BigFraction(null, BigInteger.ONE);
67          } catch (NullPointerException npe) {
68              // expected
69          }
70          try {
71              new BigFraction(BigInteger.ONE, null);
72          } catch (NullPointerException npe) {
73              // expected
74          }
75          try {
76              new BigFraction(BigInteger.ONE, BigInteger.ZERO);
77          } catch (ArithmeticException npe) {
78              // expected
79          }
80          try {
81              new BigFraction(2.0 * Integer.MAX_VALUE, 1.0e-5, 100000);
82          } catch (FractionConversionException fce) {
83              // expected
84          }
85      }
86  
87      public void testGoldenRatio() {
88          try {
89              // the golden ratio is notoriously a difficult number for continuous
90              // fraction
91              new BigFraction((1 + Math.sqrt(5)) / 2, 1.0e-12, 25);
92              fail("an exception should have been thrown");
93          } catch (ConvergenceException ce) {
94              // expected behavior
95          } catch (Exception e) {
96              fail("wrong exception caught");
97          }
98      }
99  
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 }