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