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 */
17package org.apache.commons.math.fraction;
18
19import java.io.Serializable;
20import java.math.BigDecimal;
21import java.math.BigInteger;
22
23import org.apache.commons.math.FieldElement;
24import org.apache.commons.math.MathRuntimeException;
25import org.apache.commons.math.exception.util.LocalizedFormats;
26import org.apache.commons.math.util.MathUtils;
27import org.apache.commons.math.util.FastMath;
28
29/**
30 * Representation of a rational number without any overflow. This class is
31 * immutable.
32 *
33 * @version $Revision: 1073687 $ $Date: 2011-02-23 11:39:25 +0100 (mer. 23 févr. 2011) $
34 * @since 2.0
35 */
36public class BigFraction
37    extends Number
38    implements FieldElement<BigFraction>, Comparable<BigFraction>, Serializable {
39
40    /** A fraction representing "2 / 1". */
41    public static final BigFraction TWO = new BigFraction(2);
42
43    /** A fraction representing "1". */
44    public static final BigFraction ONE = new BigFraction(1);
45
46    /** A fraction representing "0". */
47    public static final BigFraction ZERO = new BigFraction(0);
48
49    /** A fraction representing "-1 / 1". */
50    public static final BigFraction MINUS_ONE = new BigFraction(-1);
51
52    /** A fraction representing "4/5". */
53    public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5);
54
55    /** A fraction representing "1/5". */
56    public static final BigFraction ONE_FIFTH = new BigFraction(1, 5);
57
58    /** A fraction representing "1/2". */
59    public static final BigFraction ONE_HALF = new BigFraction(1, 2);
60
61    /** A fraction representing "1/4". */
62    public static final BigFraction ONE_QUARTER = new BigFraction(1, 4);
63
64    /** A fraction representing "1/3". */
65    public static final BigFraction ONE_THIRD = new BigFraction(1, 3);
66
67    /** A fraction representing "3/5". */
68    public static final BigFraction THREE_FIFTHS = new BigFraction(3, 5);
69
70    /** A fraction representing "3/4". */
71    public static final BigFraction THREE_QUARTERS = new BigFraction(3, 4);
72
73    /** A fraction representing "2/5". */
74    public static final BigFraction TWO_FIFTHS = new BigFraction(2, 5);
75
76    /** A fraction representing "2/4". */
77    public static final BigFraction TWO_QUARTERS = new BigFraction(2, 4);
78
79    /** A fraction representing "2/3". */
80    public static final BigFraction TWO_THIRDS = new BigFraction(2, 3);
81
82    /** Serializable version identifier. */
83    private static final long serialVersionUID = -5630213147331578515L;
84
85    /** <code>BigInteger</code> representation of 100. */
86    private static final BigInteger ONE_HUNDRED_DOUBLE = BigInteger.valueOf(100);
87
88    /** The numerator. */
89    private final BigInteger numerator;
90
91    /** The denominator. */
92    private final BigInteger denominator;
93
94    /**
95     * <p>
96     * Create a {@link BigFraction} equivalent to the passed <tt>BigInteger</tt>, ie
97     * "num / 1".
98     * </p>
99     *
100     * @param num
101     *            the numerator.
102     */
103    public BigFraction(final BigInteger num) {
104        this(num, BigInteger.ONE);
105    }
106
107    /**
108     * Create a {@link BigFraction} given the numerator and denominator as
109     * {@code BigInteger}. The {@link BigFraction} is reduced to lowest terms.
110     *
111     * @param num the numerator, must not be {@code null}.
112     * @param den the denominator, must not be {@code null}..
113     * @throws ArithmeticException if the denominator is zero.
114     */
115    public BigFraction(BigInteger num, BigInteger den) {
116        if (num == null) {
117            throw new NullPointerException(LocalizedFormats.NUMERATOR.getSourceString());
118        }
119        if (den == null) {
120            throw new NullPointerException(LocalizedFormats.DENOMINATOR.getSourceString());
121        }
122        if (BigInteger.ZERO.equals(den)) {
123            throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
124        }
125        if (BigInteger.ZERO.equals(num)) {
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 (BigInteger.ZERO.compareTo(den) > 0) {
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
155     * double value exactly, considering its internal bits representation.
156     * This does work for all values except NaN and infinities and does
157     * not requires any loop or 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 IllegalArgumentException if value is NaN or infinite
170     */
171    public BigFraction(final double value) throws IllegalArgumentException {
172        if (Double.isNaN(value)) {
173            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NAN_VALUE_CONVERSION);
174        }
175        if (Double.isInfinite(value)) {
176            throw MathRuntimeException.createIllegalArgumentException(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 = 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     */
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     */
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        if (a0 > overflow) {
275            throw new FractionConversionException(value, a0, 1l);
276        }
277
278        // check for (almost) integer arguments, which should not go
279        // to iterations.
280        if (FastMath.abs(a0 - value) < epsilon) {
281            numerator = BigInteger.valueOf(a0);
282            denominator = BigInteger.ONE;
283            return;
284        }
285
286        long p0 = 1;
287        long q0 = 0;
288        long p1 = a0;
289        long q1 = 1;
290
291        long p2 = 0;
292        long q2 = 1;
293
294        int n = 0;
295        boolean stop = false;
296        do {
297            ++n;
298            final double r1 = 1.0 / (r0 - a0);
299            final long a1 = (long) FastMath.floor(r1);
300            p2 = (a1 * p1) + p0;
301            q2 = (a1 * q1) + q0;
302            if ((p2 > overflow) || (q2 > overflow)) {
303                throw new FractionConversionException(value, p2, q2);
304            }
305
306            final double convergent = (double) p2 / (double) q2;
307            if ((n < maxIterations) &&
308                (FastMath.abs(convergent - value) > epsilon) &&
309                (q2 < maxDenominator)) {
310                p0 = p1;
311                p1 = p2;
312                q0 = q1;
313                q1 = q2;
314                a0 = a1;
315                r0 = r1;
316            } else {
317                stop = true;
318            }
319        } while (!stop);
320
321        if (n >= maxIterations) {
322            throw new FractionConversionException(value, maxIterations);
323        }
324
325        if (q2 < maxDenominator) {
326            numerator   = BigInteger.valueOf(p2);
327            denominator = BigInteger.valueOf(q2);
328        } else {
329            numerator   = BigInteger.valueOf(p1);
330            denominator = BigInteger.valueOf(q1);
331        }
332    }
333
334    /**
335     * Create a fraction given the double value and maximum denominator.
336     * <p>
337     * References:
338     * <ul>
339     * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
340     * Continued Fraction</a> equations (11) and (22)-(26)</li>
341     * </ul>
342     * </p>
343     *
344     * @param value
345     *            the double value to convert to a fraction.
346     * @param maxDenominator
347     *            The maximum allowed value for denominator.
348     * @throws FractionConversionException
349     *             if the continued fraction failed to converge.
350     */
351    public BigFraction(final double value, final int maxDenominator)
352        throws FractionConversionException {
353        this(value, 0, maxDenominator, 100);
354    }
355
356    /**
357     * <p>
358     * Create a {@link BigFraction} equivalent to the passed <tt>int</tt>, ie
359     * "num / 1".
360     * </p>
361     *
362     * @param num
363     *            the numerator.
364     */
365    public BigFraction(final int num) {
366        this(BigInteger.valueOf(num), BigInteger.ONE);
367    }
368
369    /**
370     * <p>
371     * Create a {@link BigFraction} given the numerator and denominator as simple
372     * <tt>int</tt>. The {@link BigFraction} is reduced to lowest terms.
373     * </p>
374     *
375     * @param num
376     *            the numerator.
377     * @param den
378     *            the denominator.
379     */
380    public BigFraction(final int num, final int den) {
381        this(BigInteger.valueOf(num), BigInteger.valueOf(den));
382    }
383
384    /**
385     * <p>
386     * Create a {@link BigFraction} equivalent to the passed long, ie "num / 1".
387     * </p>
388     *
389     * @param num
390     *            the numerator.
391     */
392    public BigFraction(final long num) {
393        this(BigInteger.valueOf(num), BigInteger.ONE);
394    }
395
396    /**
397     * <p>
398     * Create a {@link BigFraction} given the numerator and denominator as simple
399     * <tt>long</tt>. The {@link BigFraction} is reduced to lowest terms.
400     * </p>
401     *
402     * @param num
403     *            the numerator.
404     * @param den
405     *            the denominator.
406     */
407    public BigFraction(final long num, final long den) {
408        this(BigInteger.valueOf(num), BigInteger.valueOf(den));
409    }
410
411    /**
412     * <p>
413     * Creates a <code>BigFraction</code> instance with the 2 parts of a fraction
414     * Y/Z.
415     * </p>
416     *
417     * <p>
418     * Any negative signs are resolved to be on the numerator.
419     * </p>
420     *
421     * @param numerator
422     *            the numerator, for example the three in 'three sevenths'.
423     * @param denominator
424     *            the denominator, for example the seven in 'three sevenths'.
425     * @return a new fraction instance, with the numerator and denominator
426     *         reduced.
427     * @throws ArithmeticException
428     *             if the denominator is <code>zero</code>.
429     */
430    public static BigFraction getReducedFraction(final int numerator,
431                                                 final int denominator) {
432        if (numerator == 0) {
433            return ZERO; // normalize zero.
434        }
435
436        return new BigFraction(numerator, denominator);
437    }
438
439    /**
440     * <p>
441     * Returns the absolute value of this {@link BigFraction}.
442     * </p>
443     *
444     * @return the absolute value as a {@link BigFraction}.
445     */
446    public BigFraction abs() {
447        return (BigInteger.ZERO.compareTo(numerator) <= 0) ? this : negate();
448    }
449
450    /**
451     * <p>
452     * Adds the value of this fraction to the passed {@link BigInteger},
453     * returning the result in reduced form.
454     * </p>
455     *
456     * @param bg
457     *            the {@link BigInteger} to add, must'nt be <code>null</code>.
458     * @return a <code>BigFraction</code> instance with the resulting values.
459     * @throws NullPointerException
460     *             if the {@link BigInteger} is <code>null</code>.
461     */
462    public BigFraction add(final BigInteger bg) {
463        return new BigFraction(numerator.add(denominator.multiply(bg)), denominator);
464    }
465
466    /**
467     * <p>
468     * Adds the value of this fraction to the passed <tt>integer</tt>, returning
469     * the result in reduced form.
470     * </p>
471     *
472     * @param i
473     *            the <tt>integer</tt> to add.
474     * @return a <code>BigFraction</code> instance with the resulting values.
475     */
476    public BigFraction add(final int i) {
477        return add(BigInteger.valueOf(i));
478    }
479
480    /**
481     * <p>
482     * Adds the value of this fraction to the passed <tt>long</tt>, returning
483     * the result in reduced form.
484     * </p>
485     *
486     * @param l
487     *            the <tt>long</tt> to add.
488     * @return a <code>BigFraction</code> instance with the resulting values.
489     */
490    public BigFraction add(final long l) {
491        return add(BigInteger.valueOf(l));
492    }
493
494    /**
495     * <p>
496     * Adds the value of this fraction to another, returning the result in
497     * reduced form.
498     * </p>
499     *
500     * @param fraction
501     *            the {@link BigFraction} to add, must not be <code>null</code>.
502     * @return a {@link BigFraction} instance with the resulting values.
503     * @throws NullPointerException if the {@link BigFraction} is {@code null}.
504     */
505    public BigFraction add(final BigFraction fraction) {
506        if (fraction == null) {
507            throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString());
508        }
509        if (ZERO.equals(fraction)) {
510            return this;
511        }
512
513        BigInteger num = null;
514        BigInteger den = null;
515
516        if (denominator.equals(fraction.denominator)) {
517            num = numerator.add(fraction.numerator);
518            den = denominator;
519        } else {
520            num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator));
521            den = denominator.multiply(fraction.denominator);
522        }
523        return new BigFraction(num, den);
524
525    }
526
527    /**
528     * <p>
529     * Gets the fraction as a <code>BigDecimal</code>. This calculates the
530     * fraction as the numerator divided by denominator.
531     * </p>
532     *
533     * @return the fraction as a <code>BigDecimal</code>.
534     * @throws ArithmeticException
535     *             if the exact quotient does not have a terminating decimal
536     *             expansion.
537     * @see BigDecimal
538     */
539    public BigDecimal bigDecimalValue() {
540        return new BigDecimal(numerator).divide(new BigDecimal(denominator));
541    }
542
543    /**
544     * <p>
545     * Gets the fraction as a <code>BigDecimal</code> following the passed
546     * rounding mode. This calculates the fraction as the numerator divided by
547     * denominator.
548     * </p>
549     *
550     * @param roundingMode
551     *            rounding mode to apply. see {@link BigDecimal} constants.
552     * @return the fraction as a <code>BigDecimal</code>.
553     * @throws IllegalArgumentException
554     *             if <tt>roundingMode</tt> does not represent a valid rounding
555     *             mode.
556     * @see BigDecimal
557     */
558    public BigDecimal bigDecimalValue(final int roundingMode) {
559        return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode);
560    }
561
562    /**
563     * <p>
564     * Gets the fraction as a <code>BigDecimal</code> following the passed scale
565     * and rounding mode. This calculates the fraction as the numerator divided
566     * by denominator.
567     * </p>
568     *
569     * @param scale
570     *            scale of the <code>BigDecimal</code> quotient to be returned.
571     *            see {@link BigDecimal} for more information.
572     * @param roundingMode
573     *            rounding mode to apply. see {@link BigDecimal} constants.
574     * @return the fraction as a <code>BigDecimal</code>.
575     * @see BigDecimal
576     */
577    public BigDecimal bigDecimalValue(final int scale, final int roundingMode) {
578        return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode);
579    }
580
581    /**
582     * <p>
583     * Compares this object to another based on size.
584     * </p>
585     *
586     * @param object
587     *            the object to compare to, must not be <code>null</code>.
588     * @return -1 if this is less than <tt>object</tt>, +1 if this is greater
589     *         than <tt>object</tt>, 0 if they are equal.
590     * @see java.lang.Comparable#compareTo(java.lang.Object)
591     */
592    public int compareTo(final BigFraction object) {
593        BigInteger nOd = numerator.multiply(object.denominator);
594        BigInteger dOn = denominator.multiply(object.numerator);
595        return nOd.compareTo(dOn);
596    }
597
598    /**
599     * <p>
600     * Divide the value of this fraction by the passed <code>BigInteger</code>,
601     * ie "this * 1 / bg", returning the result in reduced form.
602     * </p>
603     *
604     * @param bg
605     *            the <code>BigInteger</code> to divide by, must not be
606     *            <code>null</code>.
607     * @return a {@link BigFraction} instance with the resulting values.
608     * @throws NullPointerException if the {@code BigInteger} is {@code null}.
609     * @throws ArithmeticException
610     *             if the fraction to divide by is zero.
611     */
612    public BigFraction divide(final BigInteger bg) {
613        if (BigInteger.ZERO.equals(bg)) {
614            throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
615        }
616        return new BigFraction(numerator, denominator.multiply(bg));
617    }
618
619    /**
620     * <p>
621     * Divide the value of this fraction by the passed <tt>int</tt>, ie
622     * "this * 1 / i", returning the result in reduced form.
623     * </p>
624     *
625     * @param i
626     *            the <tt>int</tt> to divide by.
627     * @return a {@link BigFraction} instance with the resulting values.
628     * @throws ArithmeticException
629     *             if the fraction to divide by is zero.
630     */
631    public BigFraction divide(final int i) {
632        return divide(BigInteger.valueOf(i));
633    }
634
635    /**
636     * <p>
637     * Divide the value of this fraction by the passed <tt>long</tt>, ie
638     * "this * 1 / l", returning the result in reduced form.
639     * </p>
640     *
641     * @param l
642     *            the <tt>long</tt> to divide by.
643     * @return a {@link BigFraction} instance with the resulting values.
644     * @throws ArithmeticException
645     *             if the fraction to divide by is zero.
646     */
647    public BigFraction divide(final long l) {
648        return divide(BigInteger.valueOf(l));
649    }
650
651    /**
652     * <p>
653     * Divide the value of this fraction by another, returning the result in
654     * reduced form.
655     * </p>
656     *
657     * @param fraction Fraction to divide by, must not be {@code null}.
658     * @return a {@link BigFraction} instance with the resulting values.
659     * @throws NullPointerException if the {@code fraction} is {@code null}.
660     * @throws ArithmeticException if the fraction to divide by is zero.
661     */
662    public BigFraction divide(final BigFraction fraction) {
663        if (fraction == null) {
664            throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString());
665        }
666        if (BigInteger.ZERO.equals(fraction.numerator)) {
667            throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
668        }
669
670        return multiply(fraction.reciprocal());
671    }
672
673    /**
674     * <p>
675     * Gets the fraction as a <tt>double</tt>. This calculates the fraction as
676     * the numerator divided by denominator.
677     * </p>
678     *
679     * @return the fraction as a <tt>double</tt>
680     * @see java.lang.Number#doubleValue()
681     */
682    @Override
683    public double doubleValue() {
684        return numerator.doubleValue() / denominator.doubleValue();
685    }
686
687    /**
688     * <p>
689     * Test for the equality of two fractions. If the lowest term numerator and
690     * denominators are the same for both fractions, the two fractions are
691     * considered to be equal.
692     * </p>
693     *
694     * @param other
695     *            fraction to test for equality to this fraction, can be
696     *            <code>null</code>.
697     * @return true if two fractions are equal, false if object is
698     *         <code>null</code>, not an instance of {@link BigFraction}, or not
699     *         equal to this fraction instance.
700     * @see java.lang.Object#equals(java.lang.Object)
701     */
702    @Override
703    public boolean equals(final Object other) {
704        boolean ret = false;
705
706        if (this == other) {
707            ret = true;
708        } else if (other instanceof BigFraction) {
709            BigFraction rhs = ((BigFraction) other).reduce();
710            BigFraction thisOne = this.reduce();
711            ret = thisOne.numerator.equals(rhs.numerator) && thisOne.denominator.equals(rhs.denominator);
712        }
713
714        return ret;
715    }
716
717    /**
718     * <p>
719     * Gets the fraction as a <tt>float</tt>. This calculates the fraction as
720     * the numerator divided by denominator.
721     * </p>
722     *
723     * @return the fraction as a <tt>float</tt>.
724     * @see java.lang.Number#floatValue()
725     */
726    @Override
727    public float floatValue() {
728        return numerator.floatValue() / denominator.floatValue();
729    }
730
731    /**
732     * <p>
733     * Access the denominator as a <code>BigInteger</code>.
734     * </p>
735     *
736     * @return the denominator as a <code>BigInteger</code>.
737     */
738    public BigInteger getDenominator() {
739        return denominator;
740    }
741
742    /**
743     * <p>
744     * Access the denominator as a <tt>int</tt>.
745     * </p>
746     *
747     * @return the denominator as a <tt>int</tt>.
748     */
749    public int getDenominatorAsInt() {
750        return denominator.intValue();
751    }
752
753    /**
754     * <p>
755     * Access the denominator as a <tt>long</tt>.
756     * </p>
757     *
758     * @return the denominator as a <tt>long</tt>.
759     */
760    public long getDenominatorAsLong() {
761        return denominator.longValue();
762    }
763
764    /**
765     * <p>
766     * Access the numerator as a <code>BigInteger</code>.
767     * </p>
768     *
769     * @return the numerator as a <code>BigInteger</code>.
770     */
771    public BigInteger getNumerator() {
772        return numerator;
773    }
774
775    /**
776     * <p>
777     * Access the numerator as a <tt>int</tt>.
778     * </p>
779     *
780     * @return the numerator as a <tt>int</tt>.
781     */
782    public int getNumeratorAsInt() {
783        return numerator.intValue();
784    }
785
786    /**
787     * <p>
788     * Access the numerator as a <tt>long</tt>.
789     * </p>
790     *
791     * @return the numerator as a <tt>long</tt>.
792     */
793    public long getNumeratorAsLong() {
794        return numerator.longValue();
795    }
796
797    /**
798     * <p>
799     * Gets a hashCode for the fraction.
800     * </p>
801     *
802     * @return a hash code value for this object.
803     * @see java.lang.Object#hashCode()
804     */
805    @Override
806    public int hashCode() {
807        return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode();
808    }
809
810    /**
811     * <p>
812     * Gets the fraction as an <tt>int</tt>. This returns the whole number part
813     * of the fraction.
814     * </p>
815     *
816     * @return the whole number fraction part.
817     * @see java.lang.Number#intValue()
818     */
819    @Override
820    public int intValue() {
821        return numerator.divide(denominator).intValue();
822    }
823
824    /**
825     * <p>
826     * Gets the fraction as a <tt>long</tt>. This returns the whole number part
827     * of the fraction.
828     * </p>
829     *
830     * @return the whole number fraction part.
831     * @see java.lang.Number#longValue()
832     */
833    @Override
834    public long longValue() {
835        return numerator.divide(denominator).longValue();
836    }
837
838    /**
839     * <p>
840     * Multiplies the value of this fraction by the passed
841     * <code>BigInteger</code>, returning the result in reduced form.
842     * </p>
843     *
844     * @param bg the {@code BigInteger} to multiply by.
845     * @return a {@code BigFraction} instance with the resulting values.
846     * @throws NullPointerException if {@code bg} is {@code null}.
847     */
848    public BigFraction multiply(final BigInteger bg) {
849        if (bg == null) {
850            throw new NullPointerException();
851        }
852        return new BigFraction(bg.multiply(numerator), denominator);
853    }
854
855    /**
856     * <p>
857     * Multiply the value of this fraction by the passed <tt>int</tt>, returning
858     * the result in reduced form.
859     * </p>
860     *
861     * @param i
862     *            the <tt>int</tt> to multiply by.
863     * @return a {@link BigFraction} instance with the resulting values.
864     */
865    public BigFraction multiply(final int i) {
866        return multiply(BigInteger.valueOf(i));
867    }
868
869    /**
870     * <p>
871     * Multiply the value of this fraction by the passed <tt>long</tt>,
872     * returning the result in reduced form.
873     * </p>
874     *
875     * @param l
876     *            the <tt>long</tt> to multiply by.
877     * @return a {@link BigFraction} instance with the resulting values.
878     */
879    public BigFraction multiply(final long l) {
880        return multiply(BigInteger.valueOf(l));
881    }
882
883    /**
884     * <p>
885     * Multiplies the value of this fraction by another, returning the result in
886     * reduced form.
887     * </p>
888     *
889     * @param fraction Fraction to multiply by, must not be {@code null}.
890     * @return a {@link BigFraction} instance with the resulting values.
891     * @throws NullPointerException if {@code fraction} is {@code null}.
892     */
893    public BigFraction multiply(final BigFraction fraction) {
894        if (fraction == null) {
895            throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString());
896        }
897        if (numerator.equals(BigInteger.ZERO) ||
898            fraction.numerator.equals(BigInteger.ZERO)) {
899            return ZERO;
900        }
901        return new BigFraction(numerator.multiply(fraction.numerator),
902                               denominator.multiply(fraction.denominator));
903    }
904
905    /**
906     * <p>
907     * Return the additive inverse of this fraction, returning the result in
908     * reduced form.
909     * </p>
910     *
911     * @return the negation of this fraction.
912     */
913    public BigFraction negate() {
914        return new BigFraction(numerator.negate(), denominator);
915    }
916
917    /**
918     * <p>
919     * Gets the fraction percentage as a <tt>double</tt>. This calculates the
920     * fraction as the numerator divided by denominator multiplied by 100.
921     * </p>
922     *
923     * @return the fraction percentage as a <tt>double</tt>.
924     */
925    public double percentageValue() {
926        return (numerator.divide(denominator)).multiply(ONE_HUNDRED_DOUBLE).doubleValue();
927    }
928
929    /**
930     * <p>
931     * Returns a <tt>integer</tt> whose value is
932     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
933     * </p>
934     *
935     * @param exponent
936     *            exponent to which this <code>BigInteger</code> is to be
937     *            raised.
938     * @return <tt>this<sup>exponent</sup></tt>.
939     */
940    public BigFraction pow(final int exponent) {
941        if (exponent < 0) {
942            return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent));
943        }
944        return new BigFraction(numerator.pow(exponent), denominator.pow(exponent));
945    }
946
947    /**
948     * <p>
949     * Returns a <code>BigFraction</code> whose value is
950     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
951     * </p>
952     *
953     * @param exponent
954     *            exponent to which this <code>BigFraction</code> is to be raised.
955     * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
956     */
957    public BigFraction pow(final long exponent) {
958        if (exponent < 0) {
959            return new BigFraction(MathUtils.pow(denominator, -exponent),
960                                   MathUtils.pow(numerator,   -exponent));
961        }
962        return new BigFraction(MathUtils.pow(numerator,   exponent),
963                               MathUtils.pow(denominator, exponent));
964    }
965
966    /**
967     * <p>
968     * Returns a <code>BigFraction</code> whose value is
969     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
970     * </p>
971     *
972     * @param exponent
973     *            exponent to which this <code>BigFraction</code> is to be raised.
974     * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
975     */
976    public BigFraction pow(final BigInteger exponent) {
977        if (exponent.compareTo(BigInteger.ZERO) < 0) {
978            final BigInteger eNeg = exponent.negate();
979            return new BigFraction(MathUtils.pow(denominator, eNeg),
980                                   MathUtils.pow(numerator,   eNeg));
981        }
982        return new BigFraction(MathUtils.pow(numerator,   exponent),
983                               MathUtils.pow(denominator, exponent));
984    }
985
986    /**
987     * <p>
988     * Returns a <code>double</code> whose value is
989     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
990     * </p>
991     *
992     * @param exponent
993     *            exponent to which this <code>BigFraction</code> is to be raised.
994     * @return <tt>this<sup>exponent</sup></tt>.
995     */
996    public double pow(final double exponent) {
997        return FastMath.pow(numerator.doubleValue(),   exponent) /
998               FastMath.pow(denominator.doubleValue(), exponent);
999    }
1000
1001    /**
1002     * <p>
1003     * Return the multiplicative inverse of this fraction.
1004     * </p>
1005     *
1006     * @return the reciprocal fraction.
1007     */
1008    public BigFraction reciprocal() {
1009        return new BigFraction(denominator, numerator);
1010    }
1011
1012    /**
1013     * <p>
1014     * Reduce this <code>BigFraction</code> to its lowest terms.
1015     * </p>
1016     *
1017     * @return the reduced <code>BigFraction</code>. It doesn't change anything if
1018     *         the fraction can be reduced.
1019     */
1020    public BigFraction reduce() {
1021        final BigInteger gcd = numerator.gcd(denominator);
1022        return new BigFraction(numerator.divide(gcd), denominator.divide(gcd));
1023    }
1024
1025    /**
1026     * <p>
1027     * Subtracts the value of an {@link BigInteger} from the value of this one,
1028     * returning the result in reduced form.
1029     * </p>
1030     *
1031     * @param bg the {@link BigInteger} to subtract, cannot be {@code null}.
1032     * @return a {@code BigFraction} instance with the resulting values.
1033     * @throws NullPointerException if the {@link BigInteger} is {@code null}.
1034     */
1035    public BigFraction subtract(final BigInteger bg) {
1036        if (bg == null) {
1037            throw new NullPointerException();
1038        }
1039        return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator);
1040    }
1041
1042    /**
1043     * <p>
1044     * Subtracts the value of an <tt>integer</tt> from the value of this one,
1045     * returning the result in reduced form.
1046     * </p>
1047     *
1048     * @param i
1049     *            the <tt>integer</tt> to subtract.
1050     * @return a <code>BigFraction</code> instance with the resulting values.
1051     */
1052    public BigFraction subtract(final int i) {
1053        return subtract(BigInteger.valueOf(i));
1054    }
1055
1056    /**
1057     * <p>
1058     * Subtracts the value of an <tt>integer</tt> from the value of this one,
1059     * returning the result in reduced form.
1060     * </p>
1061     *
1062     * @param l
1063     *            the <tt>long</tt> to subtract.
1064     * @return a <code>BigFraction</code> instance with the resulting values, or
1065     *         this object if the <tt>long</tt> is zero.
1066     */
1067    public BigFraction subtract(final long l) {
1068        return subtract(BigInteger.valueOf(l));
1069    }
1070
1071    /**
1072     * <p>
1073     * Subtracts the value of another fraction from the value of this one,
1074     * returning the result in reduced form.
1075     * </p>
1076     *
1077     * @param fraction {@link BigFraction} to subtract, must not be {@code null}.
1078     * @return a {@link BigFraction} instance with the resulting values
1079     * @throws NullPointerException if the {@code fraction} is {@code null}.
1080     */
1081    public BigFraction subtract(final BigFraction fraction) {
1082        if (fraction == null) {
1083            throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString());
1084        }
1085        if (ZERO.equals(fraction)) {
1086            return this;
1087        }
1088
1089        BigInteger num = null;
1090        BigInteger den = null;
1091        if (denominator.equals(fraction.denominator)) {
1092            num = numerator.subtract(fraction.numerator);
1093            den = denominator;
1094        } else {
1095            num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator));
1096            den = denominator.multiply(fraction.denominator);
1097        }
1098        return new BigFraction(num, den);
1099
1100    }
1101
1102    /**
1103     * <p>
1104     * Returns the <code>String</code> representing this fraction, ie
1105     * "num / dem" or just "num" if the denominator is one.
1106     * </p>
1107     *
1108     * @return a string representation of the fraction.
1109     * @see java.lang.Object#toString()
1110     */
1111    @Override
1112    public String toString() {
1113        String str = null;
1114        if (BigInteger.ONE.equals(denominator)) {
1115            str = numerator.toString();
1116        } else if (BigInteger.ZERO.equals(numerator)) {
1117            str = "0";
1118        } else {
1119            str = numerator + " / " + denominator;
1120        }
1121        return str;
1122    }
1123
1124    /** {@inheritDoc} */
1125    public BigFractionField getField() {
1126        return BigFractionField.getInstance();
1127    }
1128
1129}
1130