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