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    }