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