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.io.Serializable;
20 import java.math.BigDecimal;
21 import java.math.BigInteger;
22 
23 import org.apache.commons.math3.FieldElement;
24 import org.apache.commons.math3.exception.MathArithmeticException;
25 import org.apache.commons.math3.exception.MathIllegalArgumentException;
26 import org.apache.commons.math3.exception.NullArgumentException;
27 import org.apache.commons.math3.exception.ZeroException;
28 import org.apache.commons.math3.exception.util.LocalizedFormats;
29 import org.apache.commons.math3.util.ArithmeticUtils;
30 import org.apache.commons.math3.util.FastMath;
31 import org.apache.commons.math3.util.MathUtils;
32 
33 /**
34  * Representation of a rational number without any overflow. This class is
35  * immutable.
36  *
37  * @since 2.0
38  */
39 public class BigFraction
40     extends Number
41     implements FieldElement<BigFraction>, Comparable<BigFraction>, Serializable {
42 
43     /** A fraction representing "2 / 1". */
44     public static final BigFraction TWO = new BigFraction(2);
45 
46     /** A fraction representing "1". */
47     public static final BigFraction ONE = new BigFraction(1);
48 
49     /** A fraction representing "0". */
50     public static final BigFraction ZERO = new BigFraction(0);
51 
52     /** A fraction representing "-1 / 1". */
53     public static final BigFraction MINUS_ONE = new BigFraction(-1);
54 
55     /** A fraction representing "4/5". */
56     public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5);
57 
58     /** A fraction representing "1/5". */
59     public static final BigFraction ONE_FIFTH = new BigFraction(1, 5);
60 
61     /** A fraction representing "1/2". */
62     public static final BigFraction ONE_HALF = new BigFraction(1, 2);
63 
64     /** A fraction representing "1/4". */
65     public static final BigFraction ONE_QUARTER = new BigFraction(1, 4);
66 
67     /** A fraction representing "1/3". */
68     public static final BigFraction ONE_THIRD = new BigFraction(1, 3);
69 
70     /** A fraction representing "3/5". */
71     public static final BigFraction THREE_FIFTHS = new BigFraction(3, 5);
72 
73     /** A fraction representing "3/4". */
74     public static final BigFraction THREE_QUARTERS = new BigFraction(3, 4);
75 
76     /** A fraction representing "2/5". */
77     public static final BigFraction TWO_FIFTHS = new BigFraction(2, 5);
78 
79     /** A fraction representing "2/4". */
80     public static final BigFraction TWO_QUARTERS = new BigFraction(2, 4);
81 
82     /** A fraction representing "2/3". */
83     public static final BigFraction TWO_THIRDS = new BigFraction(2, 3);
84 
85     /** Serializable version identifier. */
86     private static final long serialVersionUID = -5630213147331578515L;
87 
88     /** <code>BigInteger</code> representation of 100. */
89     private static final BigInteger ONE_HUNDRED = BigInteger.valueOf(100);
90 
91     /** The numerator. */
92     private final BigInteger numerator;
93 
94     /** The denominator. */
95     private final BigInteger denominator;
96 
97     /**
98      * <p>
99      * Create a {@link BigFraction} equivalent to the passed {@code BigInteger}, ie
100      * "num / 1".
101      * </p>
102      *
103      * @param num
104      *            the numerator.
105      */
BigFraction(final BigInteger num)106     public BigFraction(final BigInteger num) {
107         this(num, BigInteger.ONE);
108     }
109 
110     /**
111      * Create a {@link BigFraction} given the numerator and denominator as
112      * {@code BigInteger}. The {@link BigFraction} is reduced to lowest terms.
113      *
114      * @param num the numerator, must not be {@code null}.
115      * @param den the denominator, must not be {@code null}.
116      * @throws ZeroException if the denominator is zero.
117      * @throws NullArgumentException if either of the arguments is null
118      */
BigFraction(BigInteger num, BigInteger den)119     public BigFraction(BigInteger num, BigInteger den) {
120         MathUtils.checkNotNull(num, LocalizedFormats.NUMERATOR);
121         MathUtils.checkNotNull(den, LocalizedFormats.DENOMINATOR);
122         if (den.signum() == 0) {
123             throw new ZeroException(LocalizedFormats.ZERO_DENOMINATOR);
124         }
125         if (num.signum() == 0) {
126             numerator   = BigInteger.ZERO;
127             denominator = BigInteger.ONE;
128         } else {
129 
130             // reduce numerator and denominator by greatest common denominator
131             final BigInteger gcd = num.gcd(den);
132             if (BigInteger.ONE.compareTo(gcd) < 0) {
133                 num = num.divide(gcd);
134                 den = den.divide(gcd);
135             }
136 
137             // move sign to numerator
138             if (den.signum() == -1) {
139                 num = num.negate();
140                 den = den.negate();
141             }
142 
143             // store the values in the final fields
144             numerator   = num;
145             denominator = den;
146 
147         }
148     }
149 
150     /**
151      * Create a fraction given the double value.
152      * <p>
153      * This constructor behaves <em>differently</em> from
154      * {@link #BigFraction(double, double, int)}. It converts the double value
155      * exactly, considering its internal bits representation. This works for all
156      * values except NaN and infinities and does not requires any loop or
157      * convergence threshold.
158      * </p>
159      * <p>
160      * Since this conversion is exact and since double numbers are sometimes
161      * approximated, the fraction created may seem strange in some cases. For example,
162      * calling <code>new BigFraction(1.0 / 3.0)</code> does <em>not</em> create
163      * the fraction 1/3, but the fraction 6004799503160661 / 18014398509481984
164      * because the double number passed to the constructor is not exactly 1/3
165      * (this number cannot be stored exactly in IEEE754).
166      * </p>
167      * @see #BigFraction(double, double, int)
168      * @param value the double value to convert to a fraction.
169      * @exception MathIllegalArgumentException if value is NaN or infinite
170      */
BigFraction(final double value)171     public BigFraction(final double value) throws MathIllegalArgumentException {
172         if (Double.isNaN(value)) {
173             throw new MathIllegalArgumentException(LocalizedFormats.NAN_VALUE_CONVERSION);
174         }
175         if (Double.isInfinite(value)) {
176             throw new MathIllegalArgumentException(LocalizedFormats.INFINITE_VALUE_CONVERSION);
177         }
178 
179         // compute m and k such that value = m * 2^k
180         final long bits     = Double.doubleToLongBits(value);
181         final long sign     = bits & 0x8000000000000000L;
182         final long exponent = bits & 0x7ff0000000000000L;
183         long m              = bits & 0x000fffffffffffffL;
184         if (exponent != 0) {
185             // this was a normalized number, add the implicit most significant bit
186             m |= 0x0010000000000000L;
187         }
188         if (sign != 0) {
189             m = -m;
190         }
191         int k = ((int) (exponent >> 52)) - 1075;
192         while (((m & 0x001ffffffffffffeL) != 0) && ((m & 0x1) == 0)) {
193             m >>= 1;
194             ++k;
195         }
196 
197         if (k < 0) {
198             numerator   = BigInteger.valueOf(m);
199             denominator = BigInteger.ZERO.flipBit(-k);
200         } else {
201             numerator   = BigInteger.valueOf(m).multiply(BigInteger.ZERO.flipBit(k));
202             denominator = BigInteger.ONE;
203         }
204 
205     }
206 
207     /**
208      * Create a fraction given the double value and maximum error allowed.
209      * <p>
210      * References:
211      * <ul>
212      * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
213      * Continued Fraction</a> equations (11) and (22)-(26)</li>
214      * </ul>
215      * </p>
216      *
217      * @param value
218      *            the double value to convert to a fraction.
219      * @param epsilon
220      *            maximum error allowed. The resulting fraction is within
221      *            <code>epsilon</code> of <code>value</code>, in absolute terms.
222      * @param maxIterations
223      *            maximum number of convergents.
224      * @throws FractionConversionException
225      *             if the continued fraction failed to converge.
226      * @see #BigFraction(double)
227      */
BigFraction(final double value, final double epsilon, final int maxIterations)228     public BigFraction(final double value, final double epsilon,
229                        final int maxIterations)
230         throws FractionConversionException {
231         this(value, epsilon, Integer.MAX_VALUE, maxIterations);
232     }
233 
234     /**
235      * Create a fraction given the double value and either the maximum error
236      * allowed or the maximum number of denominator digits.
237      * <p>
238      *
239      * NOTE: This constructor is called with EITHER - a valid epsilon value and
240      * the maxDenominator set to Integer.MAX_VALUE (that way the maxDenominator
241      * has no effect). OR - a valid maxDenominator value and the epsilon value
242      * set to zero (that way epsilon only has effect if there is an exact match
243      * before the maxDenominator value is reached).
244      * </p>
245      * <p>
246      *
247      * It has been done this way so that the same code can be (re)used for both
248      * scenarios. However this could be confusing to users if it were part of
249      * the public API and this constructor should therefore remain PRIVATE.
250      * </p>
251      *
252      * See JIRA issue ticket MATH-181 for more details:
253      *
254      * https://issues.apache.org/jira/browse/MATH-181
255      *
256      * @param value
257      *            the double value to convert to a fraction.
258      * @param epsilon
259      *            maximum error allowed. The resulting fraction is within
260      *            <code>epsilon</code> of <code>value</code>, in absolute terms.
261      * @param maxDenominator
262      *            maximum denominator value allowed.
263      * @param maxIterations
264      *            maximum number of convergents.
265      * @throws FractionConversionException
266      *             if the continued fraction failed to converge.
267      */
BigFraction(final double value, final double epsilon, final int maxDenominator, int maxIterations)268     private BigFraction(final double value, final double epsilon,
269                         final int maxDenominator, int maxIterations)
270         throws FractionConversionException {
271         long overflow = Integer.MAX_VALUE;
272         double r0 = value;
273         long a0 = (long) FastMath.floor(r0);
274 
275         if (FastMath.abs(a0) > overflow) {
276             throw new FractionConversionException(value, a0, 1l);
277         }
278 
279         // check for (almost) integer arguments, which should not go
280         // to iterations.
281         if (FastMath.abs(a0 - value) < epsilon) {
282             numerator = BigInteger.valueOf(a0);
283             denominator = BigInteger.ONE;
284             return;
285         }
286 
287         long p0 = 1;
288         long q0 = 0;
289         long p1 = a0;
290         long q1 = 1;
291 
292         long p2 = 0;
293         long q2 = 1;
294 
295         int n = 0;
296         boolean stop = false;
297         do {
298             ++n;
299             final double r1 = 1.0 / (r0 - a0);
300             final long a1 = (long) FastMath.floor(r1);
301             p2 = (a1 * p1) + p0;
302             q2 = (a1 * q1) + q0;
303             if ((p2 > overflow) || (q2 > overflow)) {
304                 // in maxDenominator mode, if the last fraction was very close to the actual value
305                 // q2 may overflow in the next iteration; in this case return the last one.
306                 if (epsilon == 0.0 && FastMath.abs(q1) < maxDenominator) {
307                     break;
308                 }
309                 throw new FractionConversionException(value, p2, q2);
310             }
311 
312             final double convergent = (double) p2 / (double) q2;
313             if ((n < maxIterations) &&
314                 (FastMath.abs(convergent - value) > epsilon) &&
315                 (q2 < maxDenominator)) {
316                 p0 = p1;
317                 p1 = p2;
318                 q0 = q1;
319                 q1 = q2;
320                 a0 = a1;
321                 r0 = r1;
322             } else {
323                 stop = true;
324             }
325         } while (!stop);
326 
327         if (n >= maxIterations) {
328             throw new FractionConversionException(value, maxIterations);
329         }
330 
331         if (q2 < maxDenominator) {
332             numerator   = BigInteger.valueOf(p2);
333             denominator = BigInteger.valueOf(q2);
334         } else {
335             numerator   = BigInteger.valueOf(p1);
336             denominator = BigInteger.valueOf(q1);
337         }
338     }
339 
340     /**
341      * Create a fraction given the double value and maximum denominator.
342      * <p>
343      * References:
344      * <ul>
345      * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
346      * Continued Fraction</a> equations (11) and (22)-(26)</li>
347      * </ul>
348      * </p>
349      *
350      * @param value
351      *            the double value to convert to a fraction.
352      * @param maxDenominator
353      *            The maximum allowed value for denominator.
354      * @throws FractionConversionException
355      *             if the continued fraction failed to converge.
356      */
BigFraction(final double value, final int maxDenominator)357     public BigFraction(final double value, final int maxDenominator)
358         throws FractionConversionException {
359         this(value, 0, maxDenominator, 100);
360     }
361 
362     /**
363      * <p>
364      * Create a {@link BigFraction} equivalent to the passed {@code int}, ie
365      * "num / 1".
366      * </p>
367      *
368      * @param num
369      *            the numerator.
370      */
BigFraction(final int num)371     public BigFraction(final int num) {
372         this(BigInteger.valueOf(num), BigInteger.ONE);
373     }
374 
375     /**
376      * <p>
377      * Create a {@link BigFraction} given the numerator and denominator as simple
378      * {@code int}. The {@link BigFraction} is reduced to lowest terms.
379      * </p>
380      *
381      * @param num
382      *            the numerator.
383      * @param den
384      *            the denominator.
385      */
BigFraction(final int num, final int den)386     public BigFraction(final int num, final int den) {
387         this(BigInteger.valueOf(num), BigInteger.valueOf(den));
388     }
389 
390     /**
391      * <p>
392      * Create a {@link BigFraction} equivalent to the passed long, ie "num / 1".
393      * </p>
394      *
395      * @param num
396      *            the numerator.
397      */
BigFraction(final long num)398     public BigFraction(final long num) {
399         this(BigInteger.valueOf(num), BigInteger.ONE);
400     }
401 
402     /**
403      * <p>
404      * Create a {@link BigFraction} given the numerator and denominator as simple
405      * {@code long}. The {@link BigFraction} is reduced to lowest terms.
406      * </p>
407      *
408      * @param num
409      *            the numerator.
410      * @param den
411      *            the denominator.
412      */
BigFraction(final long num, final long den)413     public BigFraction(final long num, final long den) {
414         this(BigInteger.valueOf(num), BigInteger.valueOf(den));
415     }
416 
417     /**
418      * <p>
419      * Creates a <code>BigFraction</code> instance with the 2 parts of a fraction
420      * Y/Z.
421      * </p>
422      *
423      * <p>
424      * Any negative signs are resolved to be on the numerator.
425      * </p>
426      *
427      * @param numerator
428      *            the numerator, for example the three in 'three sevenths'.
429      * @param denominator
430      *            the denominator, for example the seven in 'three sevenths'.
431      * @return a new fraction instance, with the numerator and denominator
432      *         reduced.
433      * @throws ArithmeticException
434      *             if the denominator is <code>zero</code>.
435      */
getReducedFraction(final int numerator, final int denominator)436     public static BigFraction getReducedFraction(final int numerator,
437                                                  final int denominator) {
438         if (numerator == 0) {
439             return ZERO; // normalize zero.
440         }
441 
442         return new BigFraction(numerator, denominator);
443     }
444 
445     /**
446      * <p>
447      * Returns the absolute value of this {@link BigFraction}.
448      * </p>
449      *
450      * @return the absolute value as a {@link BigFraction}.
451      */
abs()452     public BigFraction abs() {
453         return (numerator.signum() == 1) ? this : negate();
454     }
455 
456     /**
457      * <p>
458      * Adds the value of this fraction to the passed {@link BigInteger},
459      * returning the result in reduced form.
460      * </p>
461      *
462      * @param bg
463      *            the {@link BigInteger} to add, must'nt be <code>null</code>.
464      * @return a <code>BigFraction</code> instance with the resulting values.
465      * @throws NullArgumentException
466      *             if the {@link BigInteger} is <code>null</code>.
467      */
add(final BigInteger bg)468     public BigFraction add(final BigInteger bg) throws NullArgumentException {
469         MathUtils.checkNotNull(bg);
470 
471         if (numerator.signum() == 0) {
472             return new BigFraction(bg);
473         }
474         if (bg.signum() == 0) {
475             return this;
476         }
477 
478         return new BigFraction(numerator.add(denominator.multiply(bg)), denominator);
479     }
480 
481     /**
482      * <p>
483      * Adds the value of this fraction to the passed {@code integer}, returning
484      * the result in reduced form.
485      * </p>
486      *
487      * @param i
488      *            the {@code integer} to add.
489      * @return a <code>BigFraction</code> instance with the resulting values.
490      */
add(final int i)491     public BigFraction add(final int i) {
492         return add(BigInteger.valueOf(i));
493     }
494 
495     /**
496      * <p>
497      * Adds the value of this fraction to the passed {@code long}, returning
498      * the result in reduced form.
499      * </p>
500      *
501      * @param l
502      *            the {@code long} to add.
503      * @return a <code>BigFraction</code> instance with the resulting values.
504      */
add(final long l)505     public BigFraction add(final long l) {
506         return add(BigInteger.valueOf(l));
507     }
508 
509     /**
510      * <p>
511      * Adds the value of this fraction to another, returning the result in
512      * reduced form.
513      * </p>
514      *
515      * @param fraction
516      *            the {@link BigFraction} to add, must not be <code>null</code>.
517      * @return a {@link BigFraction} instance with the resulting values.
518      * @throws NullArgumentException if the {@link BigFraction} is {@code null}.
519      */
add(final BigFraction fraction)520     public BigFraction add(final BigFraction fraction) {
521         if (fraction == null) {
522             throw new NullArgumentException(LocalizedFormats.FRACTION);
523         }
524         if (fraction.numerator.signum() == 0) {
525             return this;
526         }
527         if (numerator.signum() == 0) {
528             return fraction;
529         }
530 
531         BigInteger num = null;
532         BigInteger den = null;
533 
534         if (denominator.equals(fraction.denominator)) {
535             num = numerator.add(fraction.numerator);
536             den = denominator;
537         } else {
538             num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator));
539             den = denominator.multiply(fraction.denominator);
540         }
541 
542         if (num.signum() == 0) {
543             return ZERO;
544         }
545 
546         return new BigFraction(num, den);
547 
548     }
549 
550     /**
551      * <p>
552      * Gets the fraction as a <code>BigDecimal</code>. This calculates the
553      * fraction as the numerator divided by denominator.
554      * </p>
555      *
556      * @return the fraction as a <code>BigDecimal</code>.
557      * @throws ArithmeticException
558      *             if the exact quotient does not have a terminating decimal
559      *             expansion.
560      * @see BigDecimal
561      */
bigDecimalValue()562     public BigDecimal bigDecimalValue() {
563         return new BigDecimal(numerator).divide(new BigDecimal(denominator));
564     }
565 
566     /**
567      * <p>
568      * Gets the fraction as a <code>BigDecimal</code> following the passed
569      * rounding mode. This calculates the fraction as the numerator divided by
570      * denominator.
571      * </p>
572      *
573      * @param roundingMode
574      *            rounding mode to apply. see {@link BigDecimal} constants.
575      * @return the fraction as a <code>BigDecimal</code>.
576      * @throws IllegalArgumentException
577      *             if {@code roundingMode} does not represent a valid rounding
578      *             mode.
579      * @see BigDecimal
580      */
bigDecimalValue(final int roundingMode)581     public BigDecimal bigDecimalValue(final int roundingMode) {
582         return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode);
583     }
584 
585     /**
586      * <p>
587      * Gets the fraction as a <code>BigDecimal</code> following the passed scale
588      * and rounding mode. This calculates the fraction as the numerator divided
589      * by denominator.
590      * </p>
591      *
592      * @param scale
593      *            scale of the <code>BigDecimal</code> quotient to be returned.
594      *            see {@link BigDecimal} for more information.
595      * @param roundingMode
596      *            rounding mode to apply. see {@link BigDecimal} constants.
597      * @return the fraction as a <code>BigDecimal</code>.
598      * @see BigDecimal
599      */
bigDecimalValue(final int scale, final int roundingMode)600     public BigDecimal bigDecimalValue(final int scale, final int roundingMode) {
601         return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode);
602     }
603 
604     /**
605      * <p>
606      * Compares this object to another based on size.
607      * </p>
608      *
609      * @param object
610      *            the object to compare to, must not be <code>null</code>.
611      * @return -1 if this is less than {@code object}, +1 if this is greater
612      *         than {@code object}, 0 if they are equal.
613      * @see java.lang.Comparable#compareTo(java.lang.Object)
614      */
compareTo(final BigFraction object)615     public int compareTo(final BigFraction object) {
616         int lhsSigNum = numerator.signum();
617         int rhsSigNum = object.numerator.signum();
618 
619         if (lhsSigNum != rhsSigNum) {
620             return (lhsSigNum > rhsSigNum) ? 1 : -1;
621         }
622         if (lhsSigNum == 0) {
623             return 0;
624         }
625 
626         BigInteger nOd = numerator.multiply(object.denominator);
627         BigInteger dOn = denominator.multiply(object.numerator);
628         return nOd.compareTo(dOn);
629     }
630 
631     /**
632      * <p>
633      * Divide the value of this fraction by the passed {@code BigInteger},
634      * ie {@code this * 1 / bg}, returning the result in reduced form.
635      * </p>
636      *
637      * @param bg the {@code BigInteger} to divide by, must not be {@code null}
638      * @return a {@link BigFraction} instance with the resulting values
639      * @throws NullArgumentException if the {@code BigInteger} is {@code null}
640      * @throws MathArithmeticException if the fraction to divide by is zero
641      */
divide(final BigInteger bg)642     public BigFraction divide(final BigInteger bg) {
643         if (bg == null) {
644             throw new NullArgumentException(LocalizedFormats.FRACTION);
645         }
646         if (bg.signum() == 0) {
647             throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
648         }
649         if (numerator.signum() == 0) {
650             return ZERO;
651         }
652         return new BigFraction(numerator, denominator.multiply(bg));
653     }
654 
655     /**
656      * <p>
657      * Divide the value of this fraction by the passed {@code int}, ie
658      * {@code this * 1 / i}, returning the result in reduced form.
659      * </p>
660      *
661      * @param i the {@code int} to divide by
662      * @return a {@link BigFraction} instance with the resulting values
663      * @throws MathArithmeticException if the fraction to divide by is zero
664      */
divide(final int i)665     public BigFraction divide(final int i) {
666         return divide(BigInteger.valueOf(i));
667     }
668 
669     /**
670      * <p>
671      * Divide the value of this fraction by the passed {@code long}, ie
672      * {@code this * 1 / l}, returning the result in reduced form.
673      * </p>
674      *
675      * @param l the {@code long} to divide by
676      * @return a {@link BigFraction} instance with the resulting values
677      * @throws MathArithmeticException if the fraction to divide by is zero
678      */
divide(final long l)679     public BigFraction divide(final long l) {
680         return divide(BigInteger.valueOf(l));
681     }
682 
683     /**
684      * <p>
685      * Divide the value of this fraction by another, returning the result in
686      * reduced form.
687      * </p>
688      *
689      * @param fraction Fraction to divide by, must not be {@code null}.
690      * @return a {@link BigFraction} instance with the resulting values.
691      * @throws NullArgumentException if the {@code fraction} is {@code null}.
692      * @throws MathArithmeticException if the fraction to divide by is zero
693      */
divide(final BigFraction fraction)694     public BigFraction divide(final BigFraction fraction) {
695         if (fraction == null) {
696             throw new NullArgumentException(LocalizedFormats.FRACTION);
697         }
698         if (fraction.numerator.signum() == 0) {
699             throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
700         }
701         if (numerator.signum() == 0) {
702             return ZERO;
703         }
704 
705         return multiply(fraction.reciprocal());
706     }
707 
708     /**
709      * <p>
710      * Gets the fraction as a {@code double}. This calculates the fraction as
711      * the numerator divided by denominator.
712      * </p>
713      *
714      * @return the fraction as a {@code double}
715      * @see java.lang.Number#doubleValue()
716      */
717     @Override
doubleValue()718     public double doubleValue() {
719         double result = numerator.doubleValue() / denominator.doubleValue();
720         if (Double.isNaN(result)) {
721             // Numerator and/or denominator must be out of range:
722             // Calculate how far to shift them to put them in range.
723             int shift = FastMath.max(numerator.bitLength(),
724                                      denominator.bitLength()) - FastMath.getExponent(Double.MAX_VALUE);
725             result = numerator.shiftRight(shift).doubleValue() /
726                 denominator.shiftRight(shift).doubleValue();
727         }
728         return result;
729     }
730 
731     /**
732      * <p>
733      * Test for the equality of two fractions. If the lowest term numerator and
734      * denominators are the same for both fractions, the two fractions are
735      * considered to be equal.
736      * </p>
737      *
738      * @param other
739      *            fraction to test for equality to this fraction, can be
740      *            <code>null</code>.
741      * @return true if two fractions are equal, false if object is
742      *         <code>null</code>, not an instance of {@link BigFraction}, or not
743      *         equal to this fraction instance.
744      * @see java.lang.Object#equals(java.lang.Object)
745      */
746     @Override
equals(final Object other)747     public boolean equals(final Object other) {
748         boolean ret = false;
749 
750         if (this == other) {
751             ret = true;
752         } else if (other instanceof BigFraction) {
753             BigFraction rhs = ((BigFraction) other).reduce();
754             BigFraction thisOne = this.reduce();
755             ret = thisOne.numerator.equals(rhs.numerator) && thisOne.denominator.equals(rhs.denominator);
756         }
757 
758         return ret;
759     }
760 
761     /**
762      * <p>
763      * Gets the fraction as a {@code float}. This calculates the fraction as
764      * the numerator divided by denominator.
765      * </p>
766      *
767      * @return the fraction as a {@code float}.
768      * @see java.lang.Number#floatValue()
769      */
770     @Override
floatValue()771     public float floatValue() {
772         float result = numerator.floatValue() / denominator.floatValue();
773         if (Double.isNaN(result)) {
774             // Numerator and/or denominator must be out of range:
775             // Calculate how far to shift them to put them in range.
776             int shift = FastMath.max(numerator.bitLength(),
777                                      denominator.bitLength()) - FastMath.getExponent(Float.MAX_VALUE);
778             result = numerator.shiftRight(shift).floatValue() /
779                 denominator.shiftRight(shift).floatValue();
780         }
781         return result;
782     }
783 
784     /**
785      * <p>
786      * Access the denominator as a <code>BigInteger</code>.
787      * </p>
788      *
789      * @return the denominator as a <code>BigInteger</code>.
790      */
getDenominator()791     public BigInteger getDenominator() {
792         return denominator;
793     }
794 
795     /**
796      * <p>
797      * Access the denominator as a {@code int}.
798      * </p>
799      *
800      * @return the denominator as a {@code int}.
801      */
getDenominatorAsInt()802     public int getDenominatorAsInt() {
803         return denominator.intValue();
804     }
805 
806     /**
807      * <p>
808      * Access the denominator as a {@code long}.
809      * </p>
810      *
811      * @return the denominator as a {@code long}.
812      */
getDenominatorAsLong()813     public long getDenominatorAsLong() {
814         return denominator.longValue();
815     }
816 
817     /**
818      * <p>
819      * Access the numerator as a <code>BigInteger</code>.
820      * </p>
821      *
822      * @return the numerator as a <code>BigInteger</code>.
823      */
getNumerator()824     public BigInteger getNumerator() {
825         return numerator;
826     }
827 
828     /**
829      * <p>
830      * Access the numerator as a {@code int}.
831      * </p>
832      *
833      * @return the numerator as a {@code int}.
834      */
getNumeratorAsInt()835     public int getNumeratorAsInt() {
836         return numerator.intValue();
837     }
838 
839     /**
840      * <p>
841      * Access the numerator as a {@code long}.
842      * </p>
843      *
844      * @return the numerator as a {@code long}.
845      */
getNumeratorAsLong()846     public long getNumeratorAsLong() {
847         return numerator.longValue();
848     }
849 
850     /**
851      * <p>
852      * Gets a hashCode for the fraction.
853      * </p>
854      *
855      * @return a hash code value for this object.
856      * @see java.lang.Object#hashCode()
857      */
858     @Override
hashCode()859     public int hashCode() {
860         return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode();
861     }
862 
863     /**
864      * <p>
865      * Gets the fraction as an {@code int}. This returns the whole number part
866      * of the fraction.
867      * </p>
868      *
869      * @return the whole number fraction part.
870      * @see java.lang.Number#intValue()
871      */
872     @Override
intValue()873     public int intValue() {
874         return numerator.divide(denominator).intValue();
875     }
876 
877     /**
878      * <p>
879      * Gets the fraction as a {@code long}. This returns the whole number part
880      * of the fraction.
881      * </p>
882      *
883      * @return the whole number fraction part.
884      * @see java.lang.Number#longValue()
885      */
886     @Override
longValue()887     public long longValue() {
888         return numerator.divide(denominator).longValue();
889     }
890 
891     /**
892      * <p>
893      * Multiplies the value of this fraction by the passed
894      * <code>BigInteger</code>, returning the result in reduced form.
895      * </p>
896      *
897      * @param bg the {@code BigInteger} to multiply by.
898      * @return a {@code BigFraction} instance with the resulting values.
899      * @throws NullArgumentException if {@code bg} is {@code null}.
900      */
multiply(final BigInteger bg)901     public BigFraction multiply(final BigInteger bg) {
902         if (bg == null) {
903             throw new NullArgumentException();
904         }
905         if (numerator.signum() == 0 || bg.signum() == 0) {
906             return ZERO;
907         }
908         return new BigFraction(bg.multiply(numerator), denominator);
909     }
910 
911     /**
912      * <p>
913      * Multiply the value of this fraction by the passed {@code int}, returning
914      * the result in reduced form.
915      * </p>
916      *
917      * @param i
918      *            the {@code int} to multiply by.
919      * @return a {@link BigFraction} instance with the resulting values.
920      */
multiply(final int i)921     public BigFraction multiply(final int i) {
922         if (i == 0 || numerator.signum() == 0) {
923             return ZERO;
924         }
925 
926         return multiply(BigInteger.valueOf(i));
927     }
928 
929     /**
930      * <p>
931      * Multiply the value of this fraction by the passed {@code long},
932      * returning the result in reduced form.
933      * </p>
934      *
935      * @param l
936      *            the {@code long} to multiply by.
937      * @return a {@link BigFraction} instance with the resulting values.
938      */
multiply(final long l)939     public BigFraction multiply(final long l) {
940         if (l == 0 || numerator.signum() == 0) {
941             return ZERO;
942         }
943 
944         return multiply(BigInteger.valueOf(l));
945     }
946 
947     /**
948      * <p>
949      * Multiplies the value of this fraction by another, returning the result in
950      * reduced form.
951      * </p>
952      *
953      * @param fraction Fraction to multiply by, must not be {@code null}.
954      * @return a {@link BigFraction} instance with the resulting values.
955      * @throws NullArgumentException if {@code fraction} is {@code null}.
956      */
multiply(final BigFraction fraction)957     public BigFraction multiply(final BigFraction fraction) {
958         if (fraction == null) {
959             throw new NullArgumentException(LocalizedFormats.FRACTION);
960         }
961         if (numerator.signum() == 0 ||
962             fraction.numerator.signum() == 0) {
963             return ZERO;
964         }
965         return new BigFraction(numerator.multiply(fraction.numerator),
966                                denominator.multiply(fraction.denominator));
967     }
968 
969     /**
970      * <p>
971      * Return the additive inverse of this fraction, returning the result in
972      * reduced form.
973      * </p>
974      *
975      * @return the negation of this fraction.
976      */
negate()977     public BigFraction negate() {
978         return new BigFraction(numerator.negate(), denominator);
979     }
980 
981     /**
982      * <p>
983      * Gets the fraction percentage as a {@code double}. This calculates the
984      * fraction as the numerator divided by denominator multiplied by 100.
985      * </p>
986      *
987      * @return the fraction percentage as a {@code double}.
988      */
percentageValue()989     public double percentageValue() {
990         return multiply(ONE_HUNDRED).doubleValue();
991     }
992 
993     /**
994      * <p>
995      * Returns a {@code BigFraction} whose value is
996      * {@code (this<sup>exponent</sup>)}, returning the result in reduced form.
997      * </p>
998      *
999      * @param exponent
1000      *            exponent to which this {@code BigFraction} is to be
1001      *            raised.
1002      * @return <tt>this<sup>exponent</sup></tt>.
1003      */
pow(final int exponent)1004     public BigFraction pow(final int exponent) {
1005         if (exponent == 0) {
1006             return ONE;
1007         }
1008         if (numerator.signum() == 0) {
1009             return this;
1010         }
1011 
1012         if (exponent < 0) {
1013             return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent));
1014         }
1015         return new BigFraction(numerator.pow(exponent), denominator.pow(exponent));
1016     }
1017 
1018     /**
1019      * <p>
1020      * Returns a <code>BigFraction</code> whose value is
1021      * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
1022      * </p>
1023      *
1024      * @param exponent
1025      *            exponent to which this <code>BigFraction</code> is to be raised.
1026      * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
1027      */
pow(final long exponent)1028     public BigFraction pow(final long exponent) {
1029         if (exponent == 0) {
1030             return ONE;
1031         }
1032         if (numerator.signum() == 0) {
1033             return this;
1034         }
1035 
1036         if (exponent < 0) {
1037             return new BigFraction(ArithmeticUtils.pow(denominator, -exponent),
1038                                    ArithmeticUtils.pow(numerator,   -exponent));
1039         }
1040         return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
1041                                ArithmeticUtils.pow(denominator, exponent));
1042     }
1043 
1044     /**
1045      * <p>
1046      * Returns a <code>BigFraction</code> whose value is
1047      * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
1048      * </p>
1049      *
1050      * @param exponent
1051      *            exponent to which this <code>BigFraction</code> is to be raised.
1052      * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
1053      */
pow(final BigInteger exponent)1054     public BigFraction pow(final BigInteger exponent) {
1055         if (exponent.signum() == 0) {
1056             return ONE;
1057         }
1058         if (numerator.signum() == 0) {
1059             return this;
1060         }
1061 
1062         if (exponent.signum() == -1) {
1063             final BigInteger eNeg = exponent.negate();
1064             return new BigFraction(ArithmeticUtils.pow(denominator, eNeg),
1065                                    ArithmeticUtils.pow(numerator,   eNeg));
1066         }
1067         return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
1068                                ArithmeticUtils.pow(denominator, exponent));
1069     }
1070 
1071     /**
1072      * <p>
1073      * Returns a <code>double</code> whose value is
1074      * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
1075      * </p>
1076      *
1077      * @param exponent
1078      *            exponent to which this <code>BigFraction</code> is to be raised.
1079      * @return <tt>this<sup>exponent</sup></tt>.
1080      */
pow(final double exponent)1081     public double pow(final double exponent) {
1082         return FastMath.pow(numerator.doubleValue(),   exponent) /
1083                FastMath.pow(denominator.doubleValue(), exponent);
1084     }
1085 
1086     /**
1087      * <p>
1088      * Return the multiplicative inverse of this fraction.
1089      * </p>
1090      *
1091      * @return the reciprocal fraction.
1092      */
reciprocal()1093     public BigFraction reciprocal() {
1094         return new BigFraction(denominator, numerator);
1095     }
1096 
1097     /**
1098      * <p>
1099      * Reduce this <code>BigFraction</code> to its lowest terms.
1100      * </p>
1101      *
1102      * @return the reduced <code>BigFraction</code>. It doesn't change anything if
1103      *         the fraction can be reduced.
1104      */
reduce()1105     public BigFraction reduce() {
1106         final BigInteger gcd = numerator.gcd(denominator);
1107 
1108         if (BigInteger.ONE.compareTo(gcd) < 0) {
1109             return new BigFraction(numerator.divide(gcd), denominator.divide(gcd));
1110         } else {
1111             return this;
1112         }
1113     }
1114 
1115     /**
1116      * <p>
1117      * Subtracts the value of an {@link BigInteger} from the value of this
1118      * {@code BigFraction}, returning the result in reduced form.
1119      * </p>
1120      *
1121      * @param bg the {@link BigInteger} to subtract, cannot be {@code null}.
1122      * @return a {@code BigFraction} instance with the resulting values.
1123      * @throws NullArgumentException if the {@link BigInteger} is {@code null}.
1124      */
subtract(final BigInteger bg)1125     public BigFraction subtract(final BigInteger bg) {
1126         if (bg == null) {
1127             throw new NullArgumentException();
1128         }
1129         if (bg.signum() == 0) {
1130             return this;
1131         }
1132         if (numerator.signum() == 0) {
1133             return new BigFraction(bg.negate());
1134         }
1135 
1136         return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator);
1137     }
1138 
1139     /**
1140      * <p>
1141      * Subtracts the value of an {@code integer} from the value of this
1142      * {@code BigFraction}, returning the result in reduced form.
1143      * </p>
1144      *
1145      * @param i the {@code integer} to subtract.
1146      * @return a {@code BigFraction} instance with the resulting values.
1147      */
subtract(final int i)1148     public BigFraction subtract(final int i) {
1149         return subtract(BigInteger.valueOf(i));
1150     }
1151 
1152     /**
1153      * <p>
1154      * Subtracts the value of a {@code long} from the value of this
1155      * {@code BigFraction}, returning the result in reduced form.
1156      * </p>
1157      *
1158      * @param l the {@code long} to subtract.
1159      * @return a {@code BigFraction} instance with the resulting values.
1160      */
subtract(final long l)1161     public BigFraction subtract(final long l) {
1162         return subtract(BigInteger.valueOf(l));
1163     }
1164 
1165     /**
1166      * <p>
1167      * Subtracts the value of another fraction from the value of this one,
1168      * returning the result in reduced form.
1169      * </p>
1170      *
1171      * @param fraction {@link BigFraction} to subtract, must not be {@code null}.
1172      * @return a {@link BigFraction} instance with the resulting values
1173      * @throws NullArgumentException if the {@code fraction} is {@code null}.
1174      */
subtract(final BigFraction fraction)1175     public BigFraction subtract(final BigFraction fraction) {
1176         if (fraction == null) {
1177             throw new NullArgumentException(LocalizedFormats.FRACTION);
1178         }
1179         if (fraction.numerator.signum() == 0) {
1180             return this;
1181         }
1182         if (numerator.signum() == 0) {
1183             return fraction.negate();
1184         }
1185 
1186         BigInteger num = null;
1187         BigInteger den = null;
1188         if (denominator.equals(fraction.denominator)) {
1189             num = numerator.subtract(fraction.numerator);
1190             den = denominator;
1191         } else {
1192             num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator));
1193             den = denominator.multiply(fraction.denominator);
1194         }
1195         return new BigFraction(num, den);
1196 
1197     }
1198 
1199     /**
1200      * <p>
1201      * Returns the <code>String</code> representing this fraction, ie
1202      * "num / dem" or just "num" if the denominator is one.
1203      * </p>
1204      *
1205      * @return a string representation of the fraction.
1206      * @see java.lang.Object#toString()
1207      */
1208     @Override
toString()1209     public String toString() {
1210         String str = null;
1211         if (BigInteger.ONE.equals(denominator)) {
1212             str = numerator.toString();
1213         } else if (BigInteger.ZERO.equals(numerator)) {
1214             str = "0";
1215         } else {
1216             str = numerator + " / " + denominator;
1217         }
1218         return str;
1219     }
1220 
1221     /** {@inheritDoc} */
getField()1222     public BigFractionField getField() {
1223         return BigFractionField.getInstance();
1224     }
1225 
1226 }
1227