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    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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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
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
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
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     */
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     */
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     */
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     */
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     */
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     */
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
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
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
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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
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} */
1222    public BigFractionField getField() {
1223        return BigFractionField.getInstance();
1224    }
1225
1226}