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