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