View Javadoc

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.math3.fraction;
18  
19  import java.math.BigDecimal;
20  import java.math.BigInteger;
21  
22  import org.apache.commons.math3.TestUtils;
23  import org.apache.commons.math3.exception.ConvergenceException;
24  import org.apache.commons.math3.exception.MathArithmeticException;
25  import org.apache.commons.math3.exception.NullArgumentException;
26  import org.apache.commons.math3.exception.ZeroException;
27  import org.apache.commons.math3.util.FastMath;
28  import org.junit.Assert;
29  import org.junit.Test;
30  
31  
32  public class BigFractionTest {
33  
34      private void assertFraction(int expectedNumerator, int expectedDenominator, BigFraction actual) {
35          Assert.assertEquals(expectedNumerator, actual.getNumeratorAsInt());
36          Assert.assertEquals(expectedDenominator, actual.getDenominatorAsInt());
37      }
38  
39      private void assertFraction(long expectedNumerator, long expectedDenominator, BigFraction actual) {
40          Assert.assertEquals(expectedNumerator, actual.getNumeratorAsLong());
41          Assert.assertEquals(expectedDenominator, actual.getDenominatorAsLong());
42      }
43  
44      @Test
45      public void testConstructor() {
46          assertFraction(0, 1, new BigFraction(0, 1));
47          assertFraction(0, 1, new BigFraction(0l, 2l));
48          assertFraction(0, 1, new BigFraction(0, -1));
49          assertFraction(1, 2, new BigFraction(1, 2));
50          assertFraction(1, 2, new BigFraction(2, 4));
51          assertFraction(-1, 2, new BigFraction(-1, 2));
52          assertFraction(-1, 2, new BigFraction(1, -2));
53          assertFraction(-1, 2, new BigFraction(-2, 4));
54          assertFraction(-1, 2, new BigFraction(2, -4));
55          assertFraction(11, 1, new BigFraction(11));
56          assertFraction(11, 1, new BigFraction(11l));
57          assertFraction(11, 1, new BigFraction(new BigInteger("11")));
58  
59          assertFraction(0, 1, new BigFraction(0.00000000000001, 1.0e-5, 100));
60          assertFraction(2, 5, new BigFraction(0.40000000000001, 1.0e-5, 100));
61          assertFraction(15, 1, new BigFraction(15.0000000000001, 1.0e-5, 100));
62  
63          Assert.assertEquals(0.00000000000001, new BigFraction(0.00000000000001).doubleValue(), 0.0);
64          Assert.assertEquals(0.40000000000001, new BigFraction(0.40000000000001).doubleValue(), 0.0);
65          Assert.assertEquals(15.0000000000001, new BigFraction(15.0000000000001).doubleValue(), 0.0);
66          assertFraction(3602879701896487l, 9007199254740992l, new BigFraction(0.40000000000001));
67          assertFraction(1055531162664967l, 70368744177664l, new BigFraction(15.0000000000001));
68          try {
69              new BigFraction(null, BigInteger.ONE);
70              Assert.fail("Expecting NullArgumentException");
71          } catch (NullArgumentException npe) {
72              // expected
73          }
74          try {
75              new BigFraction(BigInteger.ONE, null);
76              Assert.fail("Expecting NullArgumentException");
77          } catch (NullArgumentException npe) {
78              // expected
79          }
80          try {
81              new BigFraction(BigInteger.ONE, BigInteger.ZERO);
82              Assert.fail("Expecting ZeroException");
83          } catch (ZeroException npe) {
84              // expected
85          }
86          try {
87              new BigFraction(2.0 * Integer.MAX_VALUE, 1.0e-5, 100000);
88              Assert.fail("Expecting FractionConversionException");
89          } catch (FractionConversionException fce) {
90              // expected
91          }
92      }
93  
94      @Test(expected=ConvergenceException.class)
95      public void testGoldenRatio() {
96          // the golden ratio is notoriously a difficult number for continuous fraction
97          new BigFraction((1 + FastMath.sqrt(5)) / 2, 1.0e-12, 25);
98      }
99  
100     // MATH-179
101     @Test
102     public void testDoubleConstructor() throws ConvergenceException {
103         assertFraction(1, 2, new BigFraction((double) 1 / (double) 2, 1.0e-5, 100));
104         assertFraction(1, 3, new BigFraction((double) 1 / (double) 3, 1.0e-5, 100));
105         assertFraction(2, 3, new BigFraction((double) 2 / (double) 3, 1.0e-5, 100));
106         assertFraction(1, 4, new BigFraction((double) 1 / (double) 4, 1.0e-5, 100));
107         assertFraction(3, 4, new BigFraction((double) 3 / (double) 4, 1.0e-5, 100));
108         assertFraction(1, 5, new BigFraction((double) 1 / (double) 5, 1.0e-5, 100));
109         assertFraction(2, 5, new BigFraction((double) 2 / (double) 5, 1.0e-5, 100));
110         assertFraction(3, 5, new BigFraction((double) 3 / (double) 5, 1.0e-5, 100));
111         assertFraction(4, 5, new BigFraction((double) 4 / (double) 5, 1.0e-5, 100));
112         assertFraction(1, 6, new BigFraction((double) 1 / (double) 6, 1.0e-5, 100));
113         assertFraction(5, 6, new BigFraction((double) 5 / (double) 6, 1.0e-5, 100));
114         assertFraction(1, 7, new BigFraction((double) 1 / (double) 7, 1.0e-5, 100));
115         assertFraction(2, 7, new BigFraction((double) 2 / (double) 7, 1.0e-5, 100));
116         assertFraction(3, 7, new BigFraction((double) 3 / (double) 7, 1.0e-5, 100));
117         assertFraction(4, 7, new BigFraction((double) 4 / (double) 7, 1.0e-5, 100));
118         assertFraction(5, 7, new BigFraction((double) 5 / (double) 7, 1.0e-5, 100));
119         assertFraction(6, 7, new BigFraction((double) 6 / (double) 7, 1.0e-5, 100));
120         assertFraction(1, 8, new BigFraction((double) 1 / (double) 8, 1.0e-5, 100));
121         assertFraction(3, 8, new BigFraction((double) 3 / (double) 8, 1.0e-5, 100));
122         assertFraction(5, 8, new BigFraction((double) 5 / (double) 8, 1.0e-5, 100));
123         assertFraction(7, 8, new BigFraction((double) 7 / (double) 8, 1.0e-5, 100));
124         assertFraction(1, 9, new BigFraction((double) 1 / (double) 9, 1.0e-5, 100));
125         assertFraction(2, 9, new BigFraction((double) 2 / (double) 9, 1.0e-5, 100));
126         assertFraction(4, 9, new BigFraction((double) 4 / (double) 9, 1.0e-5, 100));
127         assertFraction(5, 9, new BigFraction((double) 5 / (double) 9, 1.0e-5, 100));
128         assertFraction(7, 9, new BigFraction((double) 7 / (double) 9, 1.0e-5, 100));
129         assertFraction(8, 9, new BigFraction((double) 8 / (double) 9, 1.0e-5, 100));
130         assertFraction(1, 10, new BigFraction((double) 1 / (double) 10, 1.0e-5, 100));
131         assertFraction(3, 10, new BigFraction((double) 3 / (double) 10, 1.0e-5, 100));
132         assertFraction(7, 10, new BigFraction((double) 7 / (double) 10, 1.0e-5, 100));
133         assertFraction(9, 10, new BigFraction((double) 9 / (double) 10, 1.0e-5, 100));
134         assertFraction(1, 11, new BigFraction((double) 1 / (double) 11, 1.0e-5, 100));
135         assertFraction(2, 11, new BigFraction((double) 2 / (double) 11, 1.0e-5, 100));
136         assertFraction(3, 11, new BigFraction((double) 3 / (double) 11, 1.0e-5, 100));
137         assertFraction(4, 11, new BigFraction((double) 4 / (double) 11, 1.0e-5, 100));
138         assertFraction(5, 11, new BigFraction((double) 5 / (double) 11, 1.0e-5, 100));
139         assertFraction(6, 11, new BigFraction((double) 6 / (double) 11, 1.0e-5, 100));
140         assertFraction(7, 11, new BigFraction((double) 7 / (double) 11, 1.0e-5, 100));
141         assertFraction(8, 11, new BigFraction((double) 8 / (double) 11, 1.0e-5, 100));
142         assertFraction(9, 11, new BigFraction((double) 9 / (double) 11, 1.0e-5, 100));
143         assertFraction(10, 11, new BigFraction((double) 10 / (double) 11, 1.0e-5, 100));
144     }
145 
146     // MATH-181
147     @Test
148     public void testDigitLimitConstructor() throws ConvergenceException {
149         assertFraction(2, 5, new BigFraction(0.4, 9));
150         assertFraction(2, 5, new BigFraction(0.4, 99));
151         assertFraction(2, 5, new BigFraction(0.4, 999));
152 
153         assertFraction(3, 5, new BigFraction(0.6152, 9));
154         assertFraction(8, 13, new BigFraction(0.6152, 99));
155         assertFraction(510, 829, new BigFraction(0.6152, 999));
156         assertFraction(769, 1250, new BigFraction(0.6152, 9999));
157     }
158 
159     @Test
160     public void testEpsilonLimitConstructor() throws ConvergenceException {
161         assertFraction(2, 5, new BigFraction(0.4, 1.0e-5, 100));
162 
163         assertFraction(3, 5, new BigFraction(0.6152, 0.02, 100));
164         assertFraction(8, 13, new BigFraction(0.6152, 1.0e-3, 100));
165         assertFraction(251, 408, new BigFraction(0.6152, 1.0e-4, 100));
166         assertFraction(251, 408, new BigFraction(0.6152, 1.0e-5, 100));
167         assertFraction(510, 829, new BigFraction(0.6152, 1.0e-6, 100));
168         assertFraction(769, 1250, new BigFraction(0.6152, 1.0e-7, 100));
169     }
170 
171     @Test
172     public void testCompareTo() {
173         BigFraction first = new BigFraction(1, 2);
174         BigFraction second = new BigFraction(1, 3);
175         BigFraction third = new BigFraction(1, 2);
176 
177         Assert.assertEquals(0, first.compareTo(first));
178         Assert.assertEquals(0, first.compareTo(third));
179         Assert.assertEquals(1, first.compareTo(second));
180         Assert.assertEquals(-1, second.compareTo(first));
181 
182         // these two values are different approximations of PI
183         // the first  one is approximately PI - 3.07e-18
184         // the second one is approximately PI + 1.936e-17
185         BigFraction pi1 = new BigFraction(1068966896, 340262731);
186         BigFraction pi2 = new BigFraction( 411557987, 131002976);
187         Assert.assertEquals(-1, pi1.compareTo(pi2));
188         Assert.assertEquals( 1, pi2.compareTo(pi1));
189         Assert.assertEquals(0.0, pi1.doubleValue() - pi2.doubleValue(), 1.0e-20);
190 
191     }
192 
193     @Test
194     public void testDoubleValue() {
195         BigFraction first = new BigFraction(1, 2);
196         BigFraction second = new BigFraction(1, 3);
197 
198         Assert.assertEquals(0.5, first.doubleValue(), 0.0);
199         Assert.assertEquals(1.0 / 3.0, second.doubleValue(), 0.0);
200     }
201 
202     // MATH-744
203     @Test
204     public void testDoubleValueForLargeNumeratorAndDenominator() {
205         final BigInteger pow400 = BigInteger.TEN.pow(400);
206         final BigInteger pow401 = BigInteger.TEN.pow(401);
207         final BigInteger two = new BigInteger("2");
208         final BigFraction large = new BigFraction(pow401.add(BigInteger.ONE),
209                                                   pow400.multiply(two));
210 
211         Assert.assertEquals(5, large.doubleValue(), 1e-15);
212     }
213 
214     // MATH-744
215     @Test
216     public void testFloatValueForLargeNumeratorAndDenominator() {
217         final BigInteger pow400 = BigInteger.TEN.pow(400);
218         final BigInteger pow401 = BigInteger.TEN.pow(401);
219         final BigInteger two = new BigInteger("2");
220         final BigFraction large = new BigFraction(pow401.add(BigInteger.ONE),
221                                                   pow400.multiply(two));
222 
223         Assert.assertEquals(5, large.floatValue(), 1e-15);
224     }
225 
226     @Test
227     public void testFloatValue() {
228         BigFraction first = new BigFraction(1, 2);
229         BigFraction second = new BigFraction(1, 3);
230 
231         Assert.assertEquals(0.5f, first.floatValue(), 0.0f);
232         Assert.assertEquals((float) (1.0 / 3.0), second.floatValue(), 0.0f);
233     }
234 
235     @Test
236     public void testIntValue() {
237         BigFraction first = new BigFraction(1, 2);
238         BigFraction second = new BigFraction(3, 2);
239 
240         Assert.assertEquals(0, first.intValue());
241         Assert.assertEquals(1, second.intValue());
242     }
243 
244     @Test
245     public void testLongValue() {
246         BigFraction first = new BigFraction(1, 2);
247         BigFraction second = new BigFraction(3, 2);
248 
249         Assert.assertEquals(0L, first.longValue());
250         Assert.assertEquals(1L, second.longValue());
251     }
252 
253     @Test
254     public void testConstructorDouble() {
255         assertFraction(1, 2, new BigFraction(0.5));
256         assertFraction(6004799503160661l, 18014398509481984l, new BigFraction(1.0 / 3.0));
257         assertFraction(6124895493223875l, 36028797018963968l, new BigFraction(17.0 / 100.0));
258         assertFraction(1784551352345559l, 562949953421312l, new BigFraction(317.0 / 100.0));
259         assertFraction(-1, 2, new BigFraction(-0.5));
260         assertFraction(-6004799503160661l, 18014398509481984l, new BigFraction(-1.0 / 3.0));
261         assertFraction(-6124895493223875l, 36028797018963968l, new BigFraction(17.0 / -100.0));
262         assertFraction(-1784551352345559l, 562949953421312l, new BigFraction(-317.0 / 100.0));
263         for (double v : new double[] { Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}) {
264             try {
265                 new BigFraction(v);
266                 Assert.fail("Expecting IllegalArgumentException");
267             } catch (IllegalArgumentException iae) {
268                 // expected
269             }
270         }
271         Assert.assertEquals(1l, new BigFraction(Double.MAX_VALUE).getDenominatorAsLong());
272         Assert.assertEquals(1l, new BigFraction(Double.longBitsToDouble(0x0010000000000000L)).getNumeratorAsLong());
273         Assert.assertEquals(1l, new BigFraction(Double.MIN_VALUE).getNumeratorAsLong());
274     }
275 
276     @Test
277     public void testAbs() {
278         BigFraction a = new BigFraction(10, 21);
279         BigFraction b = new BigFraction(-10, 21);
280         BigFraction c = new BigFraction(10, -21);
281 
282         assertFraction(10, 21, a.abs());
283         assertFraction(10, 21, b.abs());
284         assertFraction(10, 21, c.abs());
285     }
286 
287     @Test
288     public void testReciprocal() {
289         BigFraction f = null;
290 
291         f = new BigFraction(50, 75);
292         f = f.reciprocal();
293         Assert.assertEquals(3, f.getNumeratorAsInt());
294         Assert.assertEquals(2, f.getDenominatorAsInt());
295 
296         f = new BigFraction(4, 3);
297         f = f.reciprocal();
298         Assert.assertEquals(3, f.getNumeratorAsInt());
299         Assert.assertEquals(4, f.getDenominatorAsInt());
300 
301         f = new BigFraction(-15, 47);
302         f = f.reciprocal();
303         Assert.assertEquals(-47, f.getNumeratorAsInt());
304         Assert.assertEquals(15, f.getDenominatorAsInt());
305 
306         f = new BigFraction(0, 3);
307         try {
308             f = f.reciprocal();
309             Assert.fail("expecting ZeroException");
310         } catch (ZeroException ex) {
311         }
312 
313         // large values
314         f = new BigFraction(Integer.MAX_VALUE, 1);
315         f = f.reciprocal();
316         Assert.assertEquals(1, f.getNumeratorAsInt());
317         Assert.assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt());
318     }
319 
320     @Test
321     public void testNegate() {
322         BigFraction f = null;
323 
324         f = new BigFraction(50, 75);
325         f = f.negate();
326         Assert.assertEquals(-2, f.getNumeratorAsInt());
327         Assert.assertEquals(3, f.getDenominatorAsInt());
328 
329         f = new BigFraction(-50, 75);
330         f = f.negate();
331         Assert.assertEquals(2, f.getNumeratorAsInt());
332         Assert.assertEquals(3, f.getDenominatorAsInt());
333 
334         // large values
335         f = new BigFraction(Integer.MAX_VALUE - 1, Integer.MAX_VALUE);
336         f = f.negate();
337         Assert.assertEquals(Integer.MIN_VALUE + 2, f.getNumeratorAsInt());
338         Assert.assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt());
339 
340     }
341 
342     @Test
343     public void testAdd() {
344         BigFraction a = new BigFraction(1, 2);
345         BigFraction b = new BigFraction(2, 3);
346 
347         assertFraction(1, 1, a.add(a));
348         assertFraction(7, 6, a.add(b));
349         assertFraction(7, 6, b.add(a));
350         assertFraction(4, 3, b.add(b));
351 
352         BigFraction f1 = new BigFraction(Integer.MAX_VALUE - 1, 1);
353         BigFraction f2 = BigFraction.ONE;
354         BigFraction f = f1.add(f2);
355         Assert.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
356         Assert.assertEquals(1, f.getDenominatorAsInt());
357 
358         f1 = new BigFraction(-1, 13 * 13 * 2 * 2);
359         f2 = new BigFraction(-2, 13 * 17 * 2);
360         f = f1.add(f2);
361         Assert.assertEquals(13 * 13 * 17 * 2 * 2, f.getDenominatorAsInt());
362         Assert.assertEquals(-17 - 2 * 13 * 2, f.getNumeratorAsInt());
363 
364         try {
365             f.add((BigFraction) null);
366             Assert.fail("expecting NullArgumentException");
367         } catch (NullArgumentException ex) {
368         }
369 
370         // if this fraction is added naively, it will overflow.
371         // check that it doesn't.
372         f1 = new BigFraction(1, 32768 * 3);
373         f2 = new BigFraction(1, 59049);
374         f = f1.add(f2);
375         Assert.assertEquals(52451, f.getNumeratorAsInt());
376         Assert.assertEquals(1934917632, f.getDenominatorAsInt());
377 
378         f1 = new BigFraction(Integer.MIN_VALUE, 3);
379         f2 = new BigFraction(1, 3);
380         f = f1.add(f2);
381         Assert.assertEquals(Integer.MIN_VALUE + 1, f.getNumeratorAsInt());
382         Assert.assertEquals(3, f.getDenominatorAsInt());
383 
384         f1 = new BigFraction(Integer.MAX_VALUE - 1, 1);
385         f = f1.add(BigInteger.ONE);
386         Assert.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
387         Assert.assertEquals(1, f.getDenominatorAsInt());
388 
389         f = f.add(BigInteger.ZERO);
390         Assert.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
391         Assert.assertEquals(1, f.getDenominatorAsInt());
392 
393         f1 = new BigFraction(Integer.MAX_VALUE - 1, 1);
394         f = f1.add(1);
395         Assert.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
396         Assert.assertEquals(1, f.getDenominatorAsInt());
397 
398         f = f.add(0);
399         Assert.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
400         Assert.assertEquals(1, f.getDenominatorAsInt());
401 
402         f1 = new BigFraction(Integer.MAX_VALUE - 1, 1);
403         f = f1.add(1l);
404         Assert.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
405         Assert.assertEquals(1, f.getDenominatorAsInt());
406 
407         f = f.add(0l);
408         Assert.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
409         Assert.assertEquals(1, f.getDenominatorAsInt());
410 
411     }
412 
413     @Test
414     public void testDivide() {
415         BigFraction a = new BigFraction(1, 2);
416         BigFraction b = new BigFraction(2, 3);
417 
418         assertFraction(1, 1, a.divide(a));
419         assertFraction(3, 4, a.divide(b));
420         assertFraction(4, 3, b.divide(a));
421         assertFraction(1, 1, b.divide(b));
422 
423         BigFraction f1 = new BigFraction(3, 5);
424         BigFraction f2 = BigFraction.ZERO;
425         try {
426             f1.divide(f2);
427             Assert.fail("expecting MathArithmeticException");
428         } catch (MathArithmeticException ex) {
429         }
430 
431         f1 = new BigFraction(0, 5);
432         f2 = new BigFraction(2, 7);
433         BigFraction f = f1.divide(f2);
434         Assert.assertSame(BigFraction.ZERO, f);
435 
436         f1 = new BigFraction(2, 7);
437         f2 = BigFraction.ONE;
438         f = f1.divide(f2);
439         Assert.assertEquals(2, f.getNumeratorAsInt());
440         Assert.assertEquals(7, f.getDenominatorAsInt());
441 
442         f1 = new BigFraction(1, Integer.MAX_VALUE);
443         f = f1.divide(f1);
444         Assert.assertEquals(1, f.getNumeratorAsInt());
445         Assert.assertEquals(1, f.getDenominatorAsInt());
446 
447         f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
448         f2 = new BigFraction(1, Integer.MAX_VALUE);
449         f = f1.divide(f2);
450         Assert.assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt());
451         Assert.assertEquals(1, f.getDenominatorAsInt());
452 
453         try {
454             f.divide((BigFraction) null);
455             Assert.fail("expecting NullArgumentException");
456         } catch (NullArgumentException ex) {
457         }
458 
459         f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
460         f = f1.divide(BigInteger.valueOf(Integer.MIN_VALUE));
461         Assert.assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt());
462         Assert.assertEquals(1, f.getNumeratorAsInt());
463 
464         f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
465         f = f1.divide(Integer.MIN_VALUE);
466         Assert.assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt());
467         Assert.assertEquals(1, f.getNumeratorAsInt());
468 
469         f1 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
470         f = f1.divide((long) Integer.MIN_VALUE);
471         Assert.assertEquals(Integer.MAX_VALUE, f.getDenominatorAsInt());
472         Assert.assertEquals(1, f.getNumeratorAsInt());
473 
474     }
475 
476     @Test
477     public void testMultiply() {
478         BigFraction a = new BigFraction(1, 2);
479         BigFraction b = new BigFraction(2, 3);
480 
481         assertFraction(1, 4, a.multiply(a));
482         assertFraction(1, 3, a.multiply(b));
483         assertFraction(1, 3, b.multiply(a));
484         assertFraction(4, 9, b.multiply(b));
485 
486         BigFraction f1 = new BigFraction(Integer.MAX_VALUE, 1);
487         BigFraction f2 = new BigFraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
488         BigFraction f = f1.multiply(f2);
489         Assert.assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt());
490         Assert.assertEquals(1, f.getDenominatorAsInt());
491 
492         f = f2.multiply(Integer.MAX_VALUE);
493         Assert.assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt());
494         Assert.assertEquals(1, f.getDenominatorAsInt());
495 
496         f = f2.multiply((long) Integer.MAX_VALUE);
497         Assert.assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt());
498         Assert.assertEquals(1, f.getDenominatorAsInt());
499 
500         try {
501             f.multiply((BigFraction) null);
502             Assert.fail("expecting NullArgumentException");
503         } catch (NullArgumentException ex) {
504         }
505 
506     }
507 
508     @Test
509     public void testSubtract() {
510         BigFraction a = new BigFraction(1, 2);
511         BigFraction b = new BigFraction(2, 3);
512 
513         assertFraction(0, 1, a.subtract(a));
514         assertFraction(-1, 6, a.subtract(b));
515         assertFraction(1, 6, b.subtract(a));
516         assertFraction(0, 1, b.subtract(b));
517 
518         BigFraction f = new BigFraction(1, 1);
519         try {
520             f.subtract((BigFraction) null);
521             Assert.fail("expecting NullArgumentException");
522         } catch (NullArgumentException ex) {
523         }
524 
525         // if this fraction is subtracted naively, it will overflow.
526         // check that it doesn't.
527         BigFraction f1 = new BigFraction(1, 32768 * 3);
528         BigFraction f2 = new BigFraction(1, 59049);
529         f = f1.subtract(f2);
530         Assert.assertEquals(-13085, f.getNumeratorAsInt());
531         Assert.assertEquals(1934917632, f.getDenominatorAsInt());
532 
533         f1 = new BigFraction(Integer.MIN_VALUE, 3);
534         f2 = new BigFraction(1, 3).negate();
535         f = f1.subtract(f2);
536         Assert.assertEquals(Integer.MIN_VALUE + 1, f.getNumeratorAsInt());
537         Assert.assertEquals(3, f.getDenominatorAsInt());
538 
539         f1 = new BigFraction(Integer.MAX_VALUE, 1);
540         f2 = BigFraction.ONE;
541         f = f1.subtract(f2);
542         Assert.assertEquals(Integer.MAX_VALUE - 1, f.getNumeratorAsInt());
543         Assert.assertEquals(1, f.getDenominatorAsInt());
544 
545     }
546 
547     @Test
548     public void testBigDecimalValue() {
549         Assert.assertEquals(new BigDecimal(0.5), new BigFraction(1, 2).bigDecimalValue());
550         Assert.assertEquals(new BigDecimal("0.0003"), new BigFraction(3, 10000).bigDecimalValue());
551         Assert.assertEquals(new BigDecimal("0"), new BigFraction(1, 3).bigDecimalValue(BigDecimal.ROUND_DOWN));
552         Assert.assertEquals(new BigDecimal("0.333"), new BigFraction(1, 3).bigDecimalValue(3, BigDecimal.ROUND_DOWN));
553     }
554 
555     @Test
556     public void testEqualsAndHashCode() {
557         BigFraction zero = new BigFraction(0, 1);
558         BigFraction nullFraction = null;
559         Assert.assertTrue(zero.equals(zero));
560         Assert.assertFalse(zero.equals(nullFraction));
561         Assert.assertFalse(zero.equals(Double.valueOf(0)));
562         BigFraction zero2 = new BigFraction(0, 2);
563         Assert.assertTrue(zero.equals(zero2));
564         Assert.assertEquals(zero.hashCode(), zero2.hashCode());
565         BigFraction one = new BigFraction(1, 1);
566         Assert.assertFalse((one.equals(zero) || zero.equals(one)));
567         Assert.assertTrue(one.equals(BigFraction.ONE));
568     }
569 
570     @Test
571     public void testGetReducedFraction() {
572         BigFraction threeFourths = new BigFraction(3, 4);
573         Assert.assertTrue(threeFourths.equals(BigFraction.getReducedFraction(6, 8)));
574         Assert.assertTrue(BigFraction.ZERO.equals(BigFraction.getReducedFraction(0, -1)));
575         try {
576             BigFraction.getReducedFraction(1, 0);
577             Assert.fail("expecting ZeroException");
578         } catch (ZeroException ex) {
579             // expected
580         }
581         Assert.assertEquals(BigFraction.getReducedFraction(2, Integer.MIN_VALUE).getNumeratorAsInt(), -1);
582         Assert.assertEquals(BigFraction.getReducedFraction(1, -1).getNumeratorAsInt(), -1);
583     }
584 
585     @Test
586     public void testPercentage() {
587         Assert.assertEquals(50.0, new BigFraction(1, 2).percentageValue(), 1.0e-15);
588     }
589 
590     @Test
591     public void testPow() {
592         Assert.assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(13));
593         Assert.assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(13l));
594         Assert.assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(BigInteger.valueOf(13l)));
595         Assert.assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(0));
596         Assert.assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(0l));
597         Assert.assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(BigInteger.valueOf(0l)));
598         Assert.assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(-13));
599         Assert.assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(-13l));
600         Assert.assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(BigInteger.valueOf(-13l)));
601     }
602 
603     @Test
604     public void testMath340() {
605         BigFraction fractionA = new BigFraction(0.00131);
606         BigFraction fractionB = new BigFraction(.37).reciprocal();
607         BigFraction errorResult = fractionA.multiply(fractionB);
608         BigFraction correctResult = new BigFraction(fractionA.getNumerator().multiply(fractionB.getNumerator()),
609                                                     fractionA.getDenominator().multiply(fractionB.getDenominator()));
610         Assert.assertEquals(correctResult, errorResult);
611     }
612 
613     @Test
614     public void testSerial() throws FractionConversionException {
615         BigFraction[] fractions = {
616             new BigFraction(3, 4), BigFraction.ONE, BigFraction.ZERO,
617             new BigFraction(17), new BigFraction(FastMath.PI, 1000),
618             new BigFraction(-5, 2)
619         };
620         for (BigFraction fraction : fractions) {
621             Assert.assertEquals(fraction, TestUtils.serializeAndRecover(fraction));
622         }
623     }
624 
625 }