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    }