001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.math3.fraction;
018
019import java.io.Serializable;
020import java.math.BigDecimal;
021import java.math.BigInteger;
022
023import org.apache.commons.math3.FieldElement;
024import org.apache.commons.math3.exception.MathArithmeticException;
025import org.apache.commons.math3.exception.MathIllegalArgumentException;
026import org.apache.commons.math3.exception.NullArgumentException;
027import org.apache.commons.math3.exception.ZeroException;
028import org.apache.commons.math3.exception.util.LocalizedFormats;
029import org.apache.commons.math3.util.ArithmeticUtils;
030import org.apache.commons.math3.util.FastMath;
031import org.apache.commons.math3.util.MathUtils;
032
033/**
034 * Representation of a rational number without any overflow. This class is
035 * immutable.
036 *
037 * @since 2.0
038 */
039public class BigFraction
040    extends Number
041    implements FieldElement<BigFraction>, Comparable<BigFraction>, Serializable {
042
043    /** A fraction representing "2 / 1". */
044    public static final BigFraction TWO = new BigFraction(2);
045
046    /** A fraction representing "1". */
047    public static final BigFraction ONE = new BigFraction(1);
048
049    /** A fraction representing "0". */
050    public static final BigFraction ZERO = new BigFraction(0);
051
052    /** A fraction representing "-1 / 1". */
053    public static final BigFraction MINUS_ONE = new BigFraction(-1);
054
055    /** A fraction representing "4/5". */
056    public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5);
057
058    /** A fraction representing "1/5". */
059    public static final BigFraction ONE_FIFTH = new BigFraction(1, 5);
060
061    /** A fraction representing "1/2". */
062    public static final BigFraction ONE_HALF = new BigFraction(1, 2);
063
064    /** A fraction representing "1/4". */
065    public static final BigFraction ONE_QUARTER = new BigFraction(1, 4);
066
067    /** A fraction representing "1/3". */
068    public static final BigFraction ONE_THIRD = new BigFraction(1, 3);
069
070    /** A fraction representing "3/5". */
071    public static final BigFraction THREE_FIFTHS = new BigFraction(3, 5);
072
073    /** A fraction representing "3/4". */
074    public static final BigFraction THREE_QUARTERS = new BigFraction(3, 4);
075
076    /** A fraction representing "2/5". */
077    public static final BigFraction TWO_FIFTHS = new BigFraction(2, 5);
078
079    /** A fraction representing "2/4". */
080    public static final BigFraction TWO_QUARTERS = new BigFraction(2, 4);
081
082    /** A fraction representing "2/3". */
083    public static final BigFraction TWO_THIRDS = new BigFraction(2, 3);
084
085    /** Serializable version identifier. */
086    private static final long serialVersionUID = -5630213147331578515L;
087
088    /** <code>BigInteger</code> representation of 100. */
089    private static final BigInteger ONE_HUNDRED = BigInteger.valueOf(100);
090
091    /** The numerator. */
092    private final BigInteger numerator;
093
094    /** The denominator. */
095    private final BigInteger denominator;
096
097    /**
098     * <p>
099     * Create a {@link BigFraction} equivalent to the passed {@code BigInteger}, ie
100     * "num / 1".
101     * </p>
102     *
103     * @param num
104     *            the numerator.
105     */
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     */
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     */
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     */
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
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
520    @Override
521    public BigFraction add(final BigFraction fraction) {
522        if (fraction == null) {
523            throw new NullArgumentException(LocalizedFormats.FRACTION);
524        }
525        if (fraction.numerator.signum() == 0) {
526            return this;
527        }
528        if (numerator.signum() == 0) {
529            return fraction;
530        }
531
532        BigInteger num = null;
533        BigInteger den = null;
534
535        if (denominator.equals(fraction.denominator)) {
536            num = numerator.add(fraction.numerator);
537            den = denominator;
538        } else {
539            num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator));
540            den = denominator.multiply(fraction.denominator);
541        }
542
543        if (num.signum() == 0) {
544            return ZERO;
545        }
546
547        return new BigFraction(num, den);
548
549    }
550
551    /**
552     * <p>
553     * Gets the fraction as a <code>BigDecimal</code>. This calculates the
554     * fraction as the numerator divided by denominator.
555     * </p>
556     *
557     * @return the fraction as a <code>BigDecimal</code>.
558     * @throws ArithmeticException
559     *             if the exact quotient does not have a terminating decimal
560     *             expansion.
561     * @see BigDecimal
562     */
563    public BigDecimal bigDecimalValue() {
564        return new BigDecimal(numerator).divide(new BigDecimal(denominator));
565    }
566
567    /**
568     * <p>
569     * Gets the fraction as a <code>BigDecimal</code> following the passed
570     * rounding mode. This calculates the fraction as the numerator divided by
571     * denominator.
572     * </p>
573     *
574     * @param roundingMode
575     *            rounding mode to apply. see {@link BigDecimal} constants.
576     * @return the fraction as a <code>BigDecimal</code>.
577     * @throws IllegalArgumentException
578     *             if {@code roundingMode} does not represent a valid rounding
579     *             mode.
580     * @see BigDecimal
581     */
582    public BigDecimal bigDecimalValue(final int roundingMode) {
583        return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode);
584    }
585
586    /**
587     * <p>
588     * Gets the fraction as a <code>BigDecimal</code> following the passed scale
589     * and rounding mode. This calculates the fraction as the numerator divided
590     * by denominator.
591     * </p>
592     *
593     * @param scale
594     *            scale of the <code>BigDecimal</code> quotient to be returned.
595     *            see {@link BigDecimal} for more information.
596     * @param roundingMode
597     *            rounding mode to apply. see {@link BigDecimal} constants.
598     * @return the fraction as a <code>BigDecimal</code>.
599     * @see BigDecimal
600     */
601    public BigDecimal bigDecimalValue(final int scale, final int roundingMode) {
602        return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode);
603    }
604
605    /**
606     * <p>
607     * Compares this object to another based on size.
608     * </p>
609     *
610     * @param object
611     *            the object to compare to, must not be <code>null</code>.
612     * @return -1 if this is less than {@code object}, +1 if this is greater
613     *         than {@code object}, 0 if they are equal.
614     * @see java.lang.Comparable#compareTo(java.lang.Object)
615     */
616    @Override
617    public int compareTo(final BigFraction object) {
618        int lhsSigNum = numerator.signum();
619        int rhsSigNum = object.numerator.signum();
620
621        if (lhsSigNum != rhsSigNum) {
622            return (lhsSigNum > rhsSigNum) ? 1 : -1;
623        }
624        if (lhsSigNum == 0) {
625            return 0;
626        }
627
628        BigInteger nOd = numerator.multiply(object.denominator);
629        BigInteger dOn = denominator.multiply(object.numerator);
630        return nOd.compareTo(dOn);
631    }
632
633    /**
634     * <p>
635     * Divide the value of this fraction by the passed {@code BigInteger},
636     * ie {@code this * 1 / bg}, returning the result in reduced form.
637     * </p>
638     *
639     * @param bg the {@code BigInteger} to divide by, must not be {@code null}
640     * @return a {@link BigFraction} instance with the resulting values
641     * @throws NullArgumentException if the {@code BigInteger} is {@code null}
642     * @throws MathArithmeticException if the fraction to divide by is zero
643     */
644    public BigFraction divide(final BigInteger bg) {
645        if (bg == null) {
646            throw new NullArgumentException(LocalizedFormats.FRACTION);
647        }
648        if (bg.signum() == 0) {
649            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
650        }
651        if (numerator.signum() == 0) {
652            return ZERO;
653        }
654        return new BigFraction(numerator, denominator.multiply(bg));
655    }
656
657    /**
658     * <p>
659     * Divide the value of this fraction by the passed {@code int}, ie
660     * {@code this * 1 / i}, returning the result in reduced form.
661     * </p>
662     *
663     * @param i the {@code int} to divide by
664     * @return a {@link BigFraction} instance with the resulting values
665     * @throws MathArithmeticException if the fraction to divide by is zero
666     */
667    public BigFraction divide(final int i) {
668        return divide(BigInteger.valueOf(i));
669    }
670
671    /**
672     * <p>
673     * Divide the value of this fraction by the passed {@code long}, ie
674     * {@code this * 1 / l}, returning the result in reduced form.
675     * </p>
676     *
677     * @param l the {@code long} to divide by
678     * @return a {@link BigFraction} instance with the resulting values
679     * @throws MathArithmeticException if the fraction to divide by is zero
680     */
681    public BigFraction divide(final long l) {
682        return divide(BigInteger.valueOf(l));
683    }
684
685    /**
686     * <p>
687     * Divide the value of this fraction by another, returning the result in
688     * reduced form.
689     * </p>
690     *
691     * @param fraction Fraction to divide by, must not be {@code null}.
692     * @return a {@link BigFraction} instance with the resulting values.
693     * @throws NullArgumentException if the {@code fraction} is {@code null}.
694     * @throws MathArithmeticException if the fraction to divide by is zero
695     */
696    @Override
697    public BigFraction divide(final BigFraction fraction) {
698        if (fraction == null) {
699            throw new NullArgumentException(LocalizedFormats.FRACTION);
700        }
701        if (fraction.numerator.signum() == 0) {
702            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
703        }
704        if (numerator.signum() == 0) {
705            return ZERO;
706        }
707
708        return multiply(fraction.reciprocal());
709    }
710
711    /**
712     * <p>
713     * Gets the fraction as a {@code double}. This calculates the fraction as
714     * the numerator divided by denominator.
715     * </p>
716     *
717     * @return the fraction as a {@code double}
718     * @see java.lang.Number#doubleValue()
719     */
720    @Override
721    public double doubleValue() {
722        double result = numerator.doubleValue() / denominator.doubleValue();
723        if (Double.isNaN(result)) {
724            // Numerator and/or denominator must be out of range:
725            // Calculate how far to shift them to put them in range.
726            int shift = FastMath.max(numerator.bitLength(),
727                                     denominator.bitLength()) - FastMath.getExponent(Double.MAX_VALUE);
728            result = numerator.shiftRight(shift).doubleValue() /
729                denominator.shiftRight(shift).doubleValue();
730        }
731        return result;
732    }
733
734    /**
735     * <p>
736     * Test for the equality of two fractions. If the lowest term numerator and
737     * denominators are the same for both fractions, the two fractions are
738     * considered to be equal.
739     * </p>
740     *
741     * @param other
742     *            fraction to test for equality to this fraction, can be
743     *            <code>null</code>.
744     * @return true if two fractions are equal, false if object is
745     *         <code>null</code>, not an instance of {@link BigFraction}, or not
746     *         equal to this fraction instance.
747     * @see java.lang.Object#equals(java.lang.Object)
748     */
749    @Override
750    public boolean equals(final Object other) {
751        boolean ret = false;
752
753        if (this == other) {
754            ret = true;
755        } else if (other instanceof BigFraction) {
756            BigFraction rhs = ((BigFraction) other).reduce();
757            BigFraction thisOne = this.reduce();
758            ret = thisOne.numerator.equals(rhs.numerator) && thisOne.denominator.equals(rhs.denominator);
759        }
760
761        return ret;
762    }
763
764    /**
765     * <p>
766     * Gets the fraction as a {@code float}. This calculates the fraction as
767     * the numerator divided by denominator.
768     * </p>
769     *
770     * @return the fraction as a {@code float}.
771     * @see java.lang.Number#floatValue()
772     */
773    @Override
774    public float floatValue() {
775        float result = numerator.floatValue() / denominator.floatValue();
776        if (Double.isNaN(result)) {
777            // Numerator and/or denominator must be out of range:
778            // Calculate how far to shift them to put them in range.
779            int shift = FastMath.max(numerator.bitLength(),
780                                     denominator.bitLength()) - FastMath.getExponent(Float.MAX_VALUE);
781            result = numerator.shiftRight(shift).floatValue() /
782                denominator.shiftRight(shift).floatValue();
783        }
784        return result;
785    }
786
787    /**
788     * <p>
789     * Access the denominator as a <code>BigInteger</code>.
790     * </p>
791     *
792     * @return the denominator as a <code>BigInteger</code>.
793     */
794    public BigInteger getDenominator() {
795        return denominator;
796    }
797
798    /**
799     * <p>
800     * Access the denominator as a {@code int}.
801     * </p>
802     *
803     * @return the denominator as a {@code int}.
804     */
805    public int getDenominatorAsInt() {
806        return denominator.intValue();
807    }
808
809    /**
810     * <p>
811     * Access the denominator as a {@code long}.
812     * </p>
813     *
814     * @return the denominator as a {@code long}.
815     */
816    public long getDenominatorAsLong() {
817        return denominator.longValue();
818    }
819
820    /**
821     * <p>
822     * Access the numerator as a <code>BigInteger</code>.
823     * </p>
824     *
825     * @return the numerator as a <code>BigInteger</code>.
826     */
827    public BigInteger getNumerator() {
828        return numerator;
829    }
830
831    /**
832     * <p>
833     * Access the numerator as a {@code int}.
834     * </p>
835     *
836     * @return the numerator as a {@code int}.
837     */
838    public int getNumeratorAsInt() {
839        return numerator.intValue();
840    }
841
842    /**
843     * <p>
844     * Access the numerator as a {@code long}.
845     * </p>
846     *
847     * @return the numerator as a {@code long}.
848     */
849    public long getNumeratorAsLong() {
850        return numerator.longValue();
851    }
852
853    /**
854     * <p>
855     * Gets a hashCode for the fraction.
856     * </p>
857     *
858     * @return a hash code value for this object.
859     * @see java.lang.Object#hashCode()
860     */
861    @Override
862    public int hashCode() {
863        return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode();
864    }
865
866    /**
867     * <p>
868     * Gets the fraction as an {@code int}. This returns the whole number part
869     * of the fraction.
870     * </p>
871     *
872     * @return the whole number fraction part.
873     * @see java.lang.Number#intValue()
874     */
875    @Override
876    public int intValue() {
877        return numerator.divide(denominator).intValue();
878    }
879
880    /**
881     * <p>
882     * Gets the fraction as a {@code long}. This returns the whole number part
883     * of the fraction.
884     * </p>
885     *
886     * @return the whole number fraction part.
887     * @see java.lang.Number#longValue()
888     */
889    @Override
890    public long longValue() {
891        return numerator.divide(denominator).longValue();
892    }
893
894    /**
895     * <p>
896     * Multiplies the value of this fraction by the passed
897     * <code>BigInteger</code>, returning the result in reduced form.
898     * </p>
899     *
900     * @param bg the {@code BigInteger} to multiply by.
901     * @return a {@code BigFraction} instance with the resulting values.
902     * @throws NullArgumentException if {@code bg} is {@code null}.
903     */
904    public BigFraction multiply(final BigInteger bg) {
905        if (bg == null) {
906            throw new NullArgumentException();
907        }
908        if (numerator.signum() == 0 || bg.signum() == 0) {
909            return ZERO;
910        }
911        return new BigFraction(bg.multiply(numerator), denominator);
912    }
913
914    /**
915     * <p>
916     * Multiply the value of this fraction by the passed {@code int}, returning
917     * the result in reduced form.
918     * </p>
919     *
920     * @param i
921     *            the {@code int} to multiply by.
922     * @return a {@link BigFraction} instance with the resulting values.
923     */
924    @Override
925    public BigFraction multiply(final int i) {
926        if (i == 0 || numerator.signum() == 0) {
927            return ZERO;
928        }
929
930        return multiply(BigInteger.valueOf(i));
931    }
932
933    /**
934     * <p>
935     * Multiply the value of this fraction by the passed {@code long},
936     * returning the result in reduced form.
937     * </p>
938     *
939     * @param l
940     *            the {@code long} to multiply by.
941     * @return a {@link BigFraction} instance with the resulting values.
942     */
943    public BigFraction multiply(final long l) {
944        if (l == 0 || numerator.signum() == 0) {
945            return ZERO;
946        }
947
948        return multiply(BigInteger.valueOf(l));
949    }
950
951    /**
952     * <p>
953     * Multiplies the value of this fraction by another, returning the result in
954     * reduced form.
955     * </p>
956     *
957     * @param fraction Fraction to multiply by, must not be {@code null}.
958     * @return a {@link BigFraction} instance with the resulting values.
959     * @throws NullArgumentException if {@code fraction} is {@code null}.
960     */
961    @Override
962    public BigFraction multiply(final BigFraction fraction) {
963        if (fraction == null) {
964            throw new NullArgumentException(LocalizedFormats.FRACTION);
965        }
966        if (numerator.signum() == 0 ||
967            fraction.numerator.signum() == 0) {
968            return ZERO;
969        }
970        return new BigFraction(numerator.multiply(fraction.numerator),
971                               denominator.multiply(fraction.denominator));
972    }
973
974    /**
975     * <p>
976     * Return the additive inverse of this fraction, returning the result in
977     * reduced form.
978     * </p>
979     *
980     * @return the negation of this fraction.
981     */
982    @Override
983    public BigFraction negate() {
984        return new BigFraction(numerator.negate(), denominator);
985    }
986
987    /**
988     * <p>
989     * Gets the fraction percentage as a {@code double}. This calculates the
990     * fraction as the numerator divided by denominator multiplied by 100.
991     * </p>
992     *
993     * @return the fraction percentage as a {@code double}.
994     */
995    public double percentageValue() {
996        return multiply(ONE_HUNDRED).doubleValue();
997    }
998
999    /**
1000     * <p>
1001     * Returns a {@code BigFraction} whose value is
1002     * {@code (this<sup>exponent</sup>)}, returning the result in reduced form.
1003     * </p>
1004     *
1005     * @param exponent
1006     *            exponent to which this {@code BigFraction} is to be
1007     *            raised.
1008     * @return <tt>this<sup>exponent</sup></tt>.
1009     */
1010    public BigFraction pow(final int exponent) {
1011        if (exponent == 0) {
1012            return ONE;
1013        }
1014        if (numerator.signum() == 0) {
1015            return this;
1016        }
1017
1018        if (exponent < 0) {
1019            return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent));
1020        }
1021        return new BigFraction(numerator.pow(exponent), denominator.pow(exponent));
1022    }
1023
1024    /**
1025     * <p>
1026     * Returns a <code>BigFraction</code> whose value is
1027     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
1028     * </p>
1029     *
1030     * @param exponent
1031     *            exponent to which this <code>BigFraction</code> is to be raised.
1032     * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
1033     */
1034    public BigFraction pow(final long exponent) {
1035        if (exponent == 0) {
1036            return ONE;
1037        }
1038        if (numerator.signum() == 0) {
1039            return this;
1040        }
1041
1042        if (exponent < 0) {
1043            return new BigFraction(ArithmeticUtils.pow(denominator, -exponent),
1044                                   ArithmeticUtils.pow(numerator,   -exponent));
1045        }
1046        return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
1047                               ArithmeticUtils.pow(denominator, exponent));
1048    }
1049
1050    /**
1051     * <p>
1052     * Returns a <code>BigFraction</code> whose value is
1053     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
1054     * </p>
1055     *
1056     * @param exponent
1057     *            exponent to which this <code>BigFraction</code> is to be raised.
1058     * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
1059     */
1060    public BigFraction pow(final BigInteger exponent) {
1061        if (exponent.signum() == 0) {
1062            return ONE;
1063        }
1064        if (numerator.signum() == 0) {
1065            return this;
1066        }
1067
1068        if (exponent.signum() == -1) {
1069            final BigInteger eNeg = exponent.negate();
1070            return new BigFraction(ArithmeticUtils.pow(denominator, eNeg),
1071                                   ArithmeticUtils.pow(numerator,   eNeg));
1072        }
1073        return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
1074                               ArithmeticUtils.pow(denominator, exponent));
1075    }
1076
1077    /**
1078     * <p>
1079     * Returns a <code>double</code> whose value is
1080     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
1081     * </p>
1082     *
1083     * @param exponent
1084     *            exponent to which this <code>BigFraction</code> is to be raised.
1085     * @return <tt>this<sup>exponent</sup></tt>.
1086     */
1087    public double pow(final double exponent) {
1088        return FastMath.pow(numerator.doubleValue(),   exponent) /
1089               FastMath.pow(denominator.doubleValue(), exponent);
1090    }
1091
1092    /**
1093     * <p>
1094     * Return the multiplicative inverse of this fraction.
1095     * </p>
1096     *
1097     * @return the reciprocal fraction.
1098     */
1099    @Override
1100    public BigFraction reciprocal() {
1101        return new BigFraction(denominator, numerator);
1102    }
1103
1104    /**
1105     * <p>
1106     * Reduce this <code>BigFraction</code> to its lowest terms.
1107     * </p>
1108     *
1109     * @return the reduced <code>BigFraction</code>. It doesn't change anything if
1110     *         the fraction can be reduced.
1111     */
1112    public BigFraction reduce() {
1113        final BigInteger gcd = numerator.gcd(denominator);
1114
1115        if (BigInteger.ONE.compareTo(gcd) < 0) {
1116            return new BigFraction(numerator.divide(gcd), denominator.divide(gcd));
1117        } else {
1118            return this;
1119        }
1120    }
1121
1122    /**
1123     * <p>
1124     * Subtracts the value of an {@link BigInteger} from the value of this
1125     * {@code BigFraction}, returning the result in reduced form.
1126     * </p>
1127     *
1128     * @param bg the {@link BigInteger} to subtract, cannot be {@code null}.
1129     * @return a {@code BigFraction} instance with the resulting values.
1130     * @throws NullArgumentException if the {@link BigInteger} is {@code null}.
1131     */
1132    public BigFraction subtract(final BigInteger bg) {
1133        if (bg == null) {
1134            throw new NullArgumentException();
1135        }
1136        if (bg.signum() == 0) {
1137            return this;
1138        }
1139        if (numerator.signum() == 0) {
1140            return new BigFraction(bg.negate());
1141        }
1142
1143        return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator);
1144    }
1145
1146    /**
1147     * <p>
1148     * Subtracts the value of an {@code integer} from the value of this
1149     * {@code BigFraction}, returning the result in reduced form.
1150     * </p>
1151     *
1152     * @param i the {@code integer} to subtract.
1153     * @return a {@code BigFraction} instance with the resulting values.
1154     */
1155    public BigFraction subtract(final int i) {
1156        return subtract(BigInteger.valueOf(i));
1157    }
1158
1159    /**
1160     * <p>
1161     * Subtracts the value of a {@code long} from the value of this
1162     * {@code BigFraction}, returning the result in reduced form.
1163     * </p>
1164     *
1165     * @param l the {@code long} to subtract.
1166     * @return a {@code BigFraction} instance with the resulting values.
1167     */
1168    public BigFraction subtract(final long l) {
1169        return subtract(BigInteger.valueOf(l));
1170    }
1171
1172    /**
1173     * <p>
1174     * Subtracts the value of another fraction from the value of this one,
1175     * returning the result in reduced form.
1176     * </p>
1177     *
1178     * @param fraction {@link BigFraction} to subtract, must not be {@code null}.
1179     * @return a {@link BigFraction} instance with the resulting values
1180     * @throws NullArgumentException if the {@code fraction} is {@code null}.
1181     */
1182    @Override
1183    public BigFraction subtract(final BigFraction fraction) {
1184        if (fraction == null) {
1185            throw new NullArgumentException(LocalizedFormats.FRACTION);
1186        }
1187        if (fraction.numerator.signum() == 0) {
1188            return this;
1189        }
1190        if (numerator.signum() == 0) {
1191            return fraction.negate();
1192        }
1193
1194        BigInteger num = null;
1195        BigInteger den = null;
1196        if (denominator.equals(fraction.denominator)) {
1197            num = numerator.subtract(fraction.numerator);
1198            den = denominator;
1199        } else {
1200            num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator));
1201            den = denominator.multiply(fraction.denominator);
1202        }
1203        return new BigFraction(num, den);
1204
1205    }
1206
1207    /**
1208     * <p>
1209     * Returns the <code>String</code> representing this fraction, ie
1210     * "num / dem" or just "num" if the denominator is one.
1211     * </p>
1212     *
1213     * @return a string representation of the fraction.
1214     * @see java.lang.Object#toString()
1215     */
1216    @Override
1217    public String toString() {
1218        String str = null;
1219        if (BigInteger.ONE.equals(denominator)) {
1220            str = numerator.toString();
1221        } else if (BigInteger.ZERO.equals(numerator)) {
1222            str = "0";
1223        } else {
1224            str = numerator + " / " + denominator;
1225        }
1226        return str;
1227    }
1228
1229    /** {@inheritDoc} */
1230    @Override
1231    public BigFractionField getField() {
1232        return BigFractionField.getInstance();
1233    }
1234
1235}