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 (BigInteger.ZERO.equals(den)) {
123            throw new ZeroException(LocalizedFormats.ZERO_DENOMINATOR);
124        }
125        if (BigInteger.ZERO.equals(num)) {
126            numerator   = BigInteger.ZERO;
127            denominator = BigInteger.ONE;
128        } else {
129
130            // reduce numerator and denominator by greatest common denominator
131            final BigInteger gcd = num.gcd(den);
132            if (BigInteger.ONE.compareTo(gcd) < 0) {
133                num = num.divide(gcd);
134                den = den.divide(gcd);
135            }
136
137            // move sign to numerator
138            if (BigInteger.ZERO.compareTo(den) > 0) {
139                num = num.negate();
140                den = den.negate();
141            }
142
143            // store the values in the final fields
144            numerator   = num;
145            denominator = den;
146
147        }
148    }
149
150    /**
151     * Create a fraction given the double value.
152     * <p>
153     * This constructor behaves <em>differently</em> from
154     * {@link #BigFraction(double, double, int)}. It converts the 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 (BigInteger.ZERO.compareTo(numerator) <= 0) ? 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        return new BigFraction(numerator.add(denominator.multiply(bg)), denominator);
471    }
472
473    /**
474     * <p>
475     * Adds the value of this fraction to the passed {@code integer}, returning
476     * the result in reduced form.
477     * </p>
478     *
479     * @param i
480     *            the {@code integer} to add.
481     * @return a <code>BigFraction</code> instance with the resulting values.
482     */
483    public BigFraction add(final int i) {
484        return add(BigInteger.valueOf(i));
485    }
486
487    /**
488     * <p>
489     * Adds the value of this fraction to the passed {@code long}, returning
490     * the result in reduced form.
491     * </p>
492     *
493     * @param l
494     *            the {@code long} to add.
495     * @return a <code>BigFraction</code> instance with the resulting values.
496     */
497    public BigFraction add(final long l) {
498        return add(BigInteger.valueOf(l));
499    }
500
501    /**
502     * <p>
503     * Adds the value of this fraction to another, returning the result in
504     * reduced form.
505     * </p>
506     *
507     * @param fraction
508     *            the {@link BigFraction} to add, must not be <code>null</code>.
509     * @return a {@link BigFraction} instance with the resulting values.
510     * @throws NullArgumentException if the {@link BigFraction} is {@code null}.
511     */
512    public BigFraction add(final BigFraction fraction) {
513        if (fraction == null) {
514            throw new NullArgumentException(LocalizedFormats.FRACTION);
515        }
516        if (ZERO.equals(fraction)) {
517            return this;
518        }
519
520        BigInteger num = null;
521        BigInteger den = null;
522
523        if (denominator.equals(fraction.denominator)) {
524            num = numerator.add(fraction.numerator);
525            den = denominator;
526        } else {
527            num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator));
528            den = denominator.multiply(fraction.denominator);
529        }
530        return new BigFraction(num, den);
531
532    }
533
534    /**
535     * <p>
536     * Gets the fraction as a <code>BigDecimal</code>. This calculates the
537     * fraction as the numerator divided by denominator.
538     * </p>
539     *
540     * @return the fraction as a <code>BigDecimal</code>.
541     * @throws ArithmeticException
542     *             if the exact quotient does not have a terminating decimal
543     *             expansion.
544     * @see BigDecimal
545     */
546    public BigDecimal bigDecimalValue() {
547        return new BigDecimal(numerator).divide(new BigDecimal(denominator));
548    }
549
550    /**
551     * <p>
552     * Gets the fraction as a <code>BigDecimal</code> following the passed
553     * rounding mode. This calculates the fraction as the numerator divided by
554     * denominator.
555     * </p>
556     *
557     * @param roundingMode
558     *            rounding mode to apply. see {@link BigDecimal} constants.
559     * @return the fraction as a <code>BigDecimal</code>.
560     * @throws IllegalArgumentException
561     *             if {@code roundingMode} does not represent a valid rounding
562     *             mode.
563     * @see BigDecimal
564     */
565    public BigDecimal bigDecimalValue(final int roundingMode) {
566        return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode);
567    }
568
569    /**
570     * <p>
571     * Gets the fraction as a <code>BigDecimal</code> following the passed scale
572     * and rounding mode. This calculates the fraction as the numerator divided
573     * by denominator.
574     * </p>
575     *
576     * @param scale
577     *            scale of the <code>BigDecimal</code> quotient to be returned.
578     *            see {@link BigDecimal} for more information.
579     * @param roundingMode
580     *            rounding mode to apply. see {@link BigDecimal} constants.
581     * @return the fraction as a <code>BigDecimal</code>.
582     * @see BigDecimal
583     */
584    public BigDecimal bigDecimalValue(final int scale, final int roundingMode) {
585        return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode);
586    }
587
588    /**
589     * <p>
590     * Compares this object to another based on size.
591     * </p>
592     *
593     * @param object
594     *            the object to compare to, must not be <code>null</code>.
595     * @return -1 if this is less than {@code object}, +1 if this is greater
596     *         than {@code object}, 0 if they are equal.
597     * @see java.lang.Comparable#compareTo(java.lang.Object)
598     */
599    public int compareTo(final BigFraction object) {
600        BigInteger nOd = numerator.multiply(object.denominator);
601        BigInteger dOn = denominator.multiply(object.numerator);
602        return nOd.compareTo(dOn);
603    }
604
605    /**
606     * <p>
607     * Divide the value of this fraction by the passed {@code BigInteger},
608     * ie {@code this * 1 / bg}, returning the result in reduced form.
609     * </p>
610     *
611     * @param bg the {@code BigInteger} to divide by, must not be {@code null}
612     * @return a {@link BigFraction} instance with the resulting values
613     * @throws NullArgumentException if the {@code BigInteger} is {@code null}
614     * @throws MathArithmeticException if the fraction to divide by is zero
615     */
616    public BigFraction divide(final BigInteger bg) {
617        if (bg == null) {
618            throw new NullArgumentException(LocalizedFormats.FRACTION);
619        }
620        if (BigInteger.ZERO.equals(bg)) {
621            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
622        }
623        return new BigFraction(numerator, denominator.multiply(bg));
624    }
625
626    /**
627     * <p>
628     * Divide the value of this fraction by the passed {@code int}, ie
629     * {@code this * 1 / i}, returning the result in reduced form.
630     * </p>
631     *
632     * @param i the {@code int} to divide by
633     * @return a {@link BigFraction} instance with the resulting values
634     * @throws MathArithmeticException if the fraction to divide by is zero
635     */
636    public BigFraction divide(final int i) {
637        return divide(BigInteger.valueOf(i));
638    }
639
640    /**
641     * <p>
642     * Divide the value of this fraction by the passed {@code long}, ie
643     * {@code this * 1 / l}, returning the result in reduced form.
644     * </p>
645     *
646     * @param l the {@code long} to divide by
647     * @return a {@link BigFraction} instance with the resulting values
648     * @throws MathArithmeticException if the fraction to divide by is zero
649     */
650    public BigFraction divide(final long l) {
651        return divide(BigInteger.valueOf(l));
652    }
653
654    /**
655     * <p>
656     * Divide the value of this fraction by another, returning the result in
657     * reduced form.
658     * </p>
659     *
660     * @param fraction Fraction to divide by, must not be {@code null}.
661     * @return a {@link BigFraction} instance with the resulting values.
662     * @throws NullArgumentException if the {@code fraction} is {@code null}.
663     * @throws MathArithmeticException if the fraction to divide by is zero
664     */
665    public BigFraction divide(final BigFraction fraction) {
666        if (fraction == null) {
667            throw new NullArgumentException(LocalizedFormats.FRACTION);
668        }
669        if (BigInteger.ZERO.equals(fraction.numerator)) {
670            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
671        }
672
673        return multiply(fraction.reciprocal());
674    }
675
676    /**
677     * <p>
678     * Gets the fraction as a {@code double}. This calculates the fraction as
679     * the numerator divided by denominator.
680     * </p>
681     *
682     * @return the fraction as a {@code double}
683     * @see java.lang.Number#doubleValue()
684     */
685    @Override
686    public double doubleValue() {
687        double result = numerator.doubleValue() / denominator.doubleValue();
688        if (Double.isNaN(result)) {
689            // Numerator and/or denominator must be out of range:
690            // Calculate how far to shift them to put them in range.
691            int shift = FastMath.max(numerator.bitLength(),
692                                     denominator.bitLength()) - FastMath.getExponent(Double.MAX_VALUE);
693            result = numerator.shiftRight(shift).doubleValue() /
694                denominator.shiftRight(shift).doubleValue();
695        }
696        return result;
697    }
698
699    /**
700     * <p>
701     * Test for the equality of two fractions. If the lowest term numerator and
702     * denominators are the same for both fractions, the two fractions are
703     * considered to be equal.
704     * </p>
705     *
706     * @param other
707     *            fraction to test for equality to this fraction, can be
708     *            <code>null</code>.
709     * @return true if two fractions are equal, false if object is
710     *         <code>null</code>, not an instance of {@link BigFraction}, or not
711     *         equal to this fraction instance.
712     * @see java.lang.Object#equals(java.lang.Object)
713     */
714    @Override
715    public boolean equals(final Object other) {
716        boolean ret = false;
717
718        if (this == other) {
719            ret = true;
720        } else if (other instanceof BigFraction) {
721            BigFraction rhs = ((BigFraction) other).reduce();
722            BigFraction thisOne = this.reduce();
723            ret = thisOne.numerator.equals(rhs.numerator) && thisOne.denominator.equals(rhs.denominator);
724        }
725
726        return ret;
727    }
728
729    /**
730     * <p>
731     * Gets the fraction as a {@code float}. This calculates the fraction as
732     * the numerator divided by denominator.
733     * </p>
734     *
735     * @return the fraction as a {@code float}.
736     * @see java.lang.Number#floatValue()
737     */
738    @Override
739    public float floatValue() {
740        float result = numerator.floatValue() / denominator.floatValue();
741        if (Double.isNaN(result)) {
742            // Numerator and/or denominator must be out of range:
743            // Calculate how far to shift them to put them in range.
744            int shift = FastMath.max(numerator.bitLength(),
745                                     denominator.bitLength()) - FastMath.getExponent(Float.MAX_VALUE);
746            result = numerator.shiftRight(shift).floatValue() /
747                denominator.shiftRight(shift).floatValue();
748        }
749        return result;
750    }
751
752    /**
753     * <p>
754     * Access the denominator as a <code>BigInteger</code>.
755     * </p>
756     *
757     * @return the denominator as a <code>BigInteger</code>.
758     */
759    public BigInteger getDenominator() {
760        return denominator;
761    }
762
763    /**
764     * <p>
765     * Access the denominator as a {@code int}.
766     * </p>
767     *
768     * @return the denominator as a {@code int}.
769     */
770    public int getDenominatorAsInt() {
771        return denominator.intValue();
772    }
773
774    /**
775     * <p>
776     * Access the denominator as a {@code long}.
777     * </p>
778     *
779     * @return the denominator as a {@code long}.
780     */
781    public long getDenominatorAsLong() {
782        return denominator.longValue();
783    }
784
785    /**
786     * <p>
787     * Access the numerator as a <code>BigInteger</code>.
788     * </p>
789     *
790     * @return the numerator as a <code>BigInteger</code>.
791     */
792    public BigInteger getNumerator() {
793        return numerator;
794    }
795
796    /**
797     * <p>
798     * Access the numerator as a {@code int}.
799     * </p>
800     *
801     * @return the numerator as a {@code int}.
802     */
803    public int getNumeratorAsInt() {
804        return numerator.intValue();
805    }
806
807    /**
808     * <p>
809     * Access the numerator as a {@code long}.
810     * </p>
811     *
812     * @return the numerator as a {@code long}.
813     */
814    public long getNumeratorAsLong() {
815        return numerator.longValue();
816    }
817
818    /**
819     * <p>
820     * Gets a hashCode for the fraction.
821     * </p>
822     *
823     * @return a hash code value for this object.
824     * @see java.lang.Object#hashCode()
825     */
826    @Override
827    public int hashCode() {
828        return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode();
829    }
830
831    /**
832     * <p>
833     * Gets the fraction as an {@code int}. This returns the whole number part
834     * of the fraction.
835     * </p>
836     *
837     * @return the whole number fraction part.
838     * @see java.lang.Number#intValue()
839     */
840    @Override
841    public int intValue() {
842        return numerator.divide(denominator).intValue();
843    }
844
845    /**
846     * <p>
847     * Gets the fraction as a {@code long}. This returns the whole number part
848     * of the fraction.
849     * </p>
850     *
851     * @return the whole number fraction part.
852     * @see java.lang.Number#longValue()
853     */
854    @Override
855    public long longValue() {
856        return numerator.divide(denominator).longValue();
857    }
858
859    /**
860     * <p>
861     * Multiplies the value of this fraction by the passed
862     * <code>BigInteger</code>, returning the result in reduced form.
863     * </p>
864     *
865     * @param bg the {@code BigInteger} to multiply by.
866     * @return a {@code BigFraction} instance with the resulting values.
867     * @throws NullArgumentException if {@code bg} is {@code null}.
868     */
869    public BigFraction multiply(final BigInteger bg) {
870        if (bg == null) {
871            throw new NullArgumentException();
872        }
873        return new BigFraction(bg.multiply(numerator), denominator);
874    }
875
876    /**
877     * <p>
878     * Multiply the value of this fraction by the passed {@code int}, returning
879     * the result in reduced form.
880     * </p>
881     *
882     * @param i
883     *            the {@code int} to multiply by.
884     * @return a {@link BigFraction} instance with the resulting values.
885     */
886    public BigFraction multiply(final int i) {
887        return multiply(BigInteger.valueOf(i));
888    }
889
890    /**
891     * <p>
892     * Multiply the value of this fraction by the passed {@code long},
893     * returning the result in reduced form.
894     * </p>
895     *
896     * @param l
897     *            the {@code long} to multiply by.
898     * @return a {@link BigFraction} instance with the resulting values.
899     */
900    public BigFraction multiply(final long l) {
901        return multiply(BigInteger.valueOf(l));
902    }
903
904    /**
905     * <p>
906     * Multiplies the value of this fraction by another, returning the result in
907     * reduced form.
908     * </p>
909     *
910     * @param fraction Fraction to multiply by, must not be {@code null}.
911     * @return a {@link BigFraction} instance with the resulting values.
912     * @throws NullArgumentException if {@code fraction} is {@code null}.
913     */
914    public BigFraction multiply(final BigFraction fraction) {
915        if (fraction == null) {
916            throw new NullArgumentException(LocalizedFormats.FRACTION);
917        }
918        if (numerator.equals(BigInteger.ZERO) ||
919            fraction.numerator.equals(BigInteger.ZERO)) {
920            return ZERO;
921        }
922        return new BigFraction(numerator.multiply(fraction.numerator),
923                               denominator.multiply(fraction.denominator));
924    }
925
926    /**
927     * <p>
928     * Return the additive inverse of this fraction, returning the result in
929     * reduced form.
930     * </p>
931     *
932     * @return the negation of this fraction.
933     */
934    public BigFraction negate() {
935        return new BigFraction(numerator.negate(), denominator);
936    }
937
938    /**
939     * <p>
940     * Gets the fraction percentage as a {@code double}. This calculates the
941     * fraction as the numerator divided by denominator multiplied by 100.
942     * </p>
943     *
944     * @return the fraction percentage as a {@code double}.
945     */
946    public double percentageValue() {
947        return multiply(ONE_HUNDRED).doubleValue();
948    }
949
950    /**
951     * <p>
952     * Returns a {@code BigFraction} whose value is
953     * {@code (this<sup>exponent</sup>)}, returning the result in reduced form.
954     * </p>
955     *
956     * @param exponent
957     *            exponent to which this {@code BigFraction} is to be
958     *            raised.
959     * @return <tt>this<sup>exponent</sup></tt>.
960     */
961    public BigFraction pow(final int exponent) {
962        if (exponent < 0) {
963            return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent));
964        }
965        return new BigFraction(numerator.pow(exponent), denominator.pow(exponent));
966    }
967
968    /**
969     * <p>
970     * Returns a <code>BigFraction</code> whose value is
971     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
972     * </p>
973     *
974     * @param exponent
975     *            exponent to which this <code>BigFraction</code> is to be raised.
976     * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
977     */
978    public BigFraction pow(final long exponent) {
979        if (exponent < 0) {
980            return new BigFraction(ArithmeticUtils.pow(denominator, -exponent),
981                                   ArithmeticUtils.pow(numerator,   -exponent));
982        }
983        return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
984                               ArithmeticUtils.pow(denominator, exponent));
985    }
986
987    /**
988     * <p>
989     * Returns a <code>BigFraction</code> whose value is
990     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
991     * </p>
992     *
993     * @param exponent
994     *            exponent to which this <code>BigFraction</code> is to be raised.
995     * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
996     */
997    public BigFraction pow(final BigInteger exponent) {
998        if (exponent.compareTo(BigInteger.ZERO) < 0) {
999            final BigInteger eNeg = exponent.negate();
1000            return new BigFraction(ArithmeticUtils.pow(denominator, eNeg),
1001                                   ArithmeticUtils.pow(numerator,   eNeg));
1002        }
1003        return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
1004                               ArithmeticUtils.pow(denominator, exponent));
1005    }
1006
1007    /**
1008     * <p>
1009     * Returns a <code>double</code> whose value is
1010     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
1011     * </p>
1012     *
1013     * @param exponent
1014     *            exponent to which this <code>BigFraction</code> is to be raised.
1015     * @return <tt>this<sup>exponent</sup></tt>.
1016     */
1017    public double pow(final double exponent) {
1018        return FastMath.pow(numerator.doubleValue(),   exponent) /
1019               FastMath.pow(denominator.doubleValue(), exponent);
1020    }
1021
1022    /**
1023     * <p>
1024     * Return the multiplicative inverse of this fraction.
1025     * </p>
1026     *
1027     * @return the reciprocal fraction.
1028     */
1029    public BigFraction reciprocal() {
1030        return new BigFraction(denominator, numerator);
1031    }
1032
1033    /**
1034     * <p>
1035     * Reduce this <code>BigFraction</code> to its lowest terms.
1036     * </p>
1037     *
1038     * @return the reduced <code>BigFraction</code>. It doesn't change anything if
1039     *         the fraction can be reduced.
1040     */
1041    public BigFraction reduce() {
1042        final BigInteger gcd = numerator.gcd(denominator);
1043        return new BigFraction(numerator.divide(gcd), denominator.divide(gcd));
1044    }
1045
1046    /**
1047     * <p>
1048     * Subtracts the value of an {@link BigInteger} from the value of this
1049     * {@code BigFraction}, returning the result in reduced form.
1050     * </p>
1051     *
1052     * @param bg the {@link BigInteger} to subtract, cannot be {@code null}.
1053     * @return a {@code BigFraction} instance with the resulting values.
1054     * @throws NullArgumentException if the {@link BigInteger} is {@code null}.
1055     */
1056    public BigFraction subtract(final BigInteger bg) {
1057        if (bg == null) {
1058            throw new NullArgumentException();
1059        }
1060        return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator);
1061    }
1062
1063    /**
1064     * <p>
1065     * Subtracts the value of an {@code integer} from the value of this
1066     * {@code BigFraction}, returning the result in reduced form.
1067     * </p>
1068     *
1069     * @param i the {@code integer} to subtract.
1070     * @return a {@code BigFraction} instance with the resulting values.
1071     */
1072    public BigFraction subtract(final int i) {
1073        return subtract(BigInteger.valueOf(i));
1074    }
1075
1076    /**
1077     * <p>
1078     * Subtracts the value of a {@code long} from the value of this
1079     * {@code BigFraction}, returning the result in reduced form.
1080     * </p>
1081     *
1082     * @param l the {@code long} to subtract.
1083     * @return a {@code BigFraction} instance with the resulting values.
1084     */
1085    public BigFraction subtract(final long l) {
1086        return subtract(BigInteger.valueOf(l));
1087    }
1088
1089    /**
1090     * <p>
1091     * Subtracts the value of another fraction from the value of this one,
1092     * returning the result in reduced form.
1093     * </p>
1094     *
1095     * @param fraction {@link BigFraction} to subtract, must not be {@code null}.
1096     * @return a {@link BigFraction} instance with the resulting values
1097     * @throws NullArgumentException if the {@code fraction} is {@code null}.
1098     */
1099    public BigFraction subtract(final BigFraction fraction) {
1100        if (fraction == null) {
1101            throw new NullArgumentException(LocalizedFormats.FRACTION);
1102        }
1103        if (ZERO.equals(fraction)) {
1104            return this;
1105        }
1106
1107        BigInteger num = null;
1108        BigInteger den = null;
1109        if (denominator.equals(fraction.denominator)) {
1110            num = numerator.subtract(fraction.numerator);
1111            den = denominator;
1112        } else {
1113            num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator));
1114            den = denominator.multiply(fraction.denominator);
1115        }
1116        return new BigFraction(num, den);
1117
1118    }
1119
1120    /**
1121     * <p>
1122     * Returns the <code>String</code> representing this fraction, ie
1123     * "num / dem" or just "num" if the denominator is one.
1124     * </p>
1125     *
1126     * @return a string representation of the fraction.
1127     * @see java.lang.Object#toString()
1128     */
1129    @Override
1130    public String toString() {
1131        String str = null;
1132        if (BigInteger.ONE.equals(denominator)) {
1133            str = numerator.toString();
1134        } else if (BigInteger.ZERO.equals(numerator)) {
1135            str = "0";
1136        } else {
1137            str = numerator + " / " + denominator;
1138        }
1139        return str;
1140    }
1141
1142    /** {@inheritDoc} */
1143    public BigFractionField getField() {
1144        return BigFractionField.getInstance();
1145    }
1146
1147}