View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.fraction;
23  
24  import java.io.Serializable;
25  import java.math.BigDecimal;
26  import java.math.BigInteger;
27  import java.math.RoundingMode;
28  import java.util.function.Function;
29  import java.util.stream.Stream;
30  
31  import org.hipparchus.FieldElement;
32  import org.hipparchus.exception.LocalizedCoreFormats;
33  import org.hipparchus.exception.MathIllegalArgumentException;
34  import org.hipparchus.exception.MathIllegalStateException;
35  import org.hipparchus.exception.MathRuntimeException;
36  import org.hipparchus.exception.NullArgumentException;
37  import org.hipparchus.fraction.ConvergentsIterator.ConvergenceStep;
38  import org.hipparchus.util.ArithmeticUtils;
39  import org.hipparchus.util.FastMath;
40  import org.hipparchus.util.MathUtils;
41  import org.hipparchus.util.Pair;
42  import org.hipparchus.util.Precision;
43  
44  /**
45   * Representation of a rational number without any overflow. This class is
46   * immutable.
47   *
48   */
49  public class BigFraction
50      extends Number
51      implements FieldElement<BigFraction>, Comparable<BigFraction>, Serializable {
52  
53      /** A fraction representing "2 / 1". */
54      public static final BigFraction TWO = new BigFraction(2);
55  
56      /** A fraction representing "1". */
57      public static final BigFraction ONE = new BigFraction(1);
58  
59      /** A fraction representing "0". */
60      public static final BigFraction ZERO = new BigFraction(0);
61  
62      /** A fraction representing "-1 / 1". */
63      public static final BigFraction MINUS_ONE = new BigFraction(-1);
64  
65      /** A fraction representing "4/5". */
66      public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5);
67  
68      /** A fraction representing "1/5". */
69      public static final BigFraction ONE_FIFTH = new BigFraction(1, 5);
70  
71      /** A fraction representing "1/2". */
72      public static final BigFraction ONE_HALF = new BigFraction(1, 2);
73  
74      /** A fraction representing "1/4". */
75      public static final BigFraction ONE_QUARTER = new BigFraction(1, 4);
76  
77      /** A fraction representing "1/3". */
78      public static final BigFraction ONE_THIRD = new BigFraction(1, 3);
79  
80      /** A fraction representing "3/5". */
81      public static final BigFraction THREE_FIFTHS = new BigFraction(3, 5);
82  
83      /** A fraction representing "3/4". */
84      public static final BigFraction THREE_QUARTERS = new BigFraction(3, 4);
85  
86      /** A fraction representing "2/5". */
87      public static final BigFraction TWO_FIFTHS = new BigFraction(2, 5);
88  
89      /** A fraction representing "2/4". */
90      public static final BigFraction TWO_QUARTERS = new BigFraction(2, 4);
91  
92      /** A fraction representing "2/3". */
93      public static final BigFraction TWO_THIRDS = new BigFraction(2, 3);
94  
95      /** Serializable version identifier. */
96      private static final long serialVersionUID = -5630213147331578515L;
97  
98      /** <code>BigInteger</code> representation of 100. */
99      private static final BigInteger ONE_HUNDRED = BigInteger.valueOf(100);
100 
101     /** Convert a convergence step to the corresponding double fraction. */
102     private static final Function<ConvergenceStep, BigFraction> STEP_TO_FRACTION = //
103             s -> new BigFraction(s.getNumerator(), s.getDenominator());
104 
105     /** The numerator. */
106     private final BigInteger numerator;
107 
108     /** The denominator. */
109     private final BigInteger denominator;
110 
111     /**
112      * <p>
113      * Create a {@link BigFraction} equivalent to the passed {@code BigInteger}, ie
114      * "num / 1".
115      * </p>
116      *
117      * @param num
118      *            the numerator.
119      */
120     public BigFraction(final BigInteger num) {
121         this(num, BigInteger.ONE);
122     }
123 
124     /**
125      * Create a {@link BigFraction} given the numerator and denominator as
126      * {@code BigInteger}. The {@link BigFraction} is reduced to lowest terms.
127      *
128      * @param num the numerator, must not be {@code null}.
129      * @param den the denominator, must not be {@code null}.
130      * @throws MathIllegalArgumentException if the denominator is zero.
131      * @throws NullArgumentException if either of the arguments is null
132      */
133     public BigFraction(BigInteger num, BigInteger den) {
134         MathUtils.checkNotNull(num, LocalizedCoreFormats.NUMERATOR);
135         MathUtils.checkNotNull(den, LocalizedCoreFormats.DENOMINATOR);
136         if (den.signum() == 0) {
137             throw new MathIllegalArgumentException(LocalizedCoreFormats.ZERO_DENOMINATOR);
138         }
139         if (num.signum() == 0) {
140             numerator   = BigInteger.ZERO;
141             denominator = BigInteger.ONE;
142         } else {
143 
144             // reduce numerator and denominator by greatest common denominator
145             final BigInteger gcd = num.gcd(den);
146             if (BigInteger.ONE.compareTo(gcd) < 0) {
147                 num = num.divide(gcd);
148                 den = den.divide(gcd);
149             }
150 
151             // move sign to numerator
152             if (den.signum() == -1) {
153                 num = num.negate();
154                 den = den.negate();
155             }
156 
157             // store the values in the final fields
158             numerator   = num;
159             denominator = den;
160 
161         }
162     }
163 
164     /**
165      * Create a fraction given the double value.
166      * <p>
167      * This constructor behaves <em>differently</em> from
168      * {@link #BigFraction(double, double, int)}. It converts the double value
169      * exactly, considering its internal bits representation. This works for all
170      * values except NaN and infinities and does not requires any loop or
171      * convergence threshold.
172      * </p>
173      * <p>
174      * Since this conversion is exact and since double numbers are sometimes
175      * approximated, the fraction created may seem strange in some cases. For example,
176      * calling <code>new BigFraction(1.0 / 3.0)</code> does <em>not</em> create
177      * the fraction 1/3, but the fraction 6004799503160661 / 18014398509481984
178      * because the double number passed to the constructor is not exactly 1/3
179      * (this number cannot be stored exactly in IEEE754).
180      * </p>
181      * @see #BigFraction(double, double, int)
182      * @param value the double value to convert to a fraction.
183      * @exception MathIllegalArgumentException if value is NaN or infinite
184      */
185     public BigFraction(final double value) throws MathIllegalArgumentException {
186         if (Double.isNaN(value)) {
187             throw new MathIllegalArgumentException(LocalizedCoreFormats.NAN_VALUE_CONVERSION);
188         }
189         if (Double.isInfinite(value)) {
190             throw new MathIllegalArgumentException(LocalizedCoreFormats.INFINITE_VALUE_CONVERSION);
191         }
192 
193         // compute m and k such that value = m * 2^k
194         final long bits     = Double.doubleToLongBits(value);
195         final long sign     = bits & 0x8000000000000000L;
196         final long exponent = bits & 0x7ff0000000000000L;
197         long m              = bits & 0x000fffffffffffffL;
198         if (exponent != 0) {
199             // this was a normalized number, add the implicit most significant bit
200             m |= 0x0010000000000000L;
201         }
202         if (sign != 0) {
203             m = -m;
204         }
205         int k = ((int) (exponent >> 52)) - 1075;
206         while (((m & 0x001ffffffffffffeL) != 0) && ((m & 0x1) == 0)) {
207             m >>= 1;
208             ++k;
209         }
210 
211         if (k < 0) {
212             numerator   = BigInteger.valueOf(m);
213             denominator = BigInteger.ZERO.flipBit(-k);
214         } else {
215             numerator   = BigInteger.valueOf(m).multiply(BigInteger.ZERO.flipBit(k));
216             denominator = BigInteger.ONE;
217         }
218 
219     }
220 
221     /**
222      * Create a fraction given the double value and maximum error allowed.
223      * <p>* References:</p>
224      * <ul>
225      * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
226      * Continued Fraction</a> equations (11) and (22)-(26)</li>
227      * </ul>
228      *
229      * @param value
230      *            the double value to convert to a fraction.
231      * @param epsilon
232      *            maximum error allowed. The resulting fraction is within
233      *            <code>epsilon</code> of <code>value</code>, in absolute terms.
234      * @param maxIterations
235      *            maximum number of convergents.
236      * @throws MathIllegalStateException
237      *             if the continued fraction failed to converge.
238      * @see #BigFraction(double)
239      */
240     public BigFraction(final double value, final double epsilon,
241                        final int maxIterations)
242         throws MathIllegalStateException {
243         ConvergenceStep converged = ConvergentsIterator.convergent(value, maxIterations, s -> {
244             final double quotient = s.getFractionValue();
245             return Precision.equals(quotient, value, 1) || FastMath.abs(quotient - value) < epsilon;
246         }).getKey();
247         if (FastMath.abs(converged.getFractionValue() - value) < epsilon) {
248             this.numerator = BigInteger.valueOf(converged.getNumerator());
249             this.denominator = BigInteger.valueOf(converged.getDenominator());
250         } else {
251             throw new MathIllegalStateException(LocalizedCoreFormats.FAILED_FRACTION_CONVERSION,
252                                                 value, maxIterations);
253         }
254     }
255 
256     /**
257      * Create a fraction given the double value and maximum denominator.
258      * <p>* References:</p>
259      * <ul>
260      * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
261      * Continued Fraction</a> equations (11) and (22)-(26)</li>
262      * </ul>
263      *
264      * @param value
265      *            the double value to convert to a fraction.
266      * @param maxDenominator
267      *            The maximum allowed value for denominator.
268      * @throws MathIllegalStateException
269      *             if the continued fraction failed to converge.
270      */
271     public BigFraction(final double value, final long maxDenominator)
272         throws MathIllegalStateException {
273         final int maxIterations = 100;
274         ConvergenceStep[] lastValid = new ConvergenceStep[1];
275         ConvergentsIterator.convergent(value, maxIterations, s -> {
276             if (s.getDenominator() < maxDenominator) {
277                 lastValid[0] = s;
278             }
279             return Precision.equals(s.getFractionValue(), value, 1);
280         });
281         if (lastValid[0] != null) {
282             this.numerator   = BigInteger.valueOf(lastValid[0].getNumerator());
283             this.denominator = BigInteger.valueOf(lastValid[0].getDenominator());
284         } else {
285             throw new MathIllegalStateException(LocalizedCoreFormats.FAILED_FRACTION_CONVERSION,
286                                                 value, maxIterations);
287         }
288     }
289 
290     /**
291      * <p>
292      * Create a {@link BigFraction} equivalent to the passed {@code int}, ie
293      * "num / 1".
294      * </p>
295      *
296      * @param num
297      *            the numerator.
298      */
299     public BigFraction(final int num) {
300         this(BigInteger.valueOf(num), BigInteger.ONE);
301     }
302 
303     /**
304      * <p>
305      * Create a {@link BigFraction} given the numerator and denominator as simple
306      * {@code int}. The {@link BigFraction} is reduced to lowest terms.
307      * </p>
308      *
309      * @param num
310      *            the numerator.
311      * @param den
312      *            the denominator.
313      */
314     public BigFraction(final int num, final int den) {
315         this(BigInteger.valueOf(num), BigInteger.valueOf(den));
316     }
317 
318     /**
319      * <p>
320      * Create a {@link BigFraction} equivalent to the passed long, ie "num / 1".
321      * </p>
322      *
323      * @param num
324      *            the numerator.
325      */
326     public BigFraction(final long num) {
327         this(BigInteger.valueOf(num), BigInteger.ONE);
328     }
329 
330     /**
331      * <p>
332      * Create a {@link BigFraction} given the numerator and denominator as simple
333      * {@code long}. The {@link BigFraction} is reduced to lowest terms.
334      * </p>
335      *
336      * @param num
337      *            the numerator.
338      * @param den
339      *            the denominator.
340      */
341     public BigFraction(final long num, final long den) {
342         this(BigInteger.valueOf(num), BigInteger.valueOf(den));
343     }
344 
345     /**
346      * A test to determine if a series of fractions has converged.
347      */
348     @FunctionalInterface
349     public interface ConvergenceTest {
350         /**
351          * Evaluates if the fraction formed by {@code numerator/denominator} satisfies
352          * this convergence test.
353          *
354          * @param numerator   the numerator
355          * @param denominator the denominator
356          * @return if this convergence test is satisfied
357          */
358         boolean test(long numerator, long denominator); // NOPMD - this is not a Junit test, PMD false positive here
359     }
360 
361     /** Generate a {@link Stream stream} of convergents from a real number.
362      * @param value value to approximate
363      * @param maxConvergents maximum number of convergents.
364      * @return stream of {@link BigFraction} convergents approximating  {@code value}
365      * @since 2.1
366      */
367     public static Stream<BigFraction> convergents(final double value, final int maxConvergents) {
368         return ConvergentsIterator.convergents(value, maxConvergents).map(STEP_TO_FRACTION);
369     }
370 
371     /**
372      * Returns the last element of the series of convergent-steps to approximate the
373      * given value.
374      * <p>
375      * The series terminates either at the first step that satisfies the given
376      * {@code convergenceTest} or after at most {@code maxConvergents} elements. The
377      * returned Pair consists of that terminal {@link BigFraction} and a
378      * {@link Boolean} that indicates if it satisfies the given convergence tests.
379      * If the returned pair's value is {@code false} the element at position
380      * {@code maxConvergents} was examined but failed to satisfy the
381      * {@code convergenceTest}. A caller can then decide to accept the result
382      * nevertheless or to discard it. This method is usually faster than
383      * {@link #convergents(double, int)} if only the terminal element is of
384      * interest.
385      *
386      * @param value           value to approximate
387      * @param maxConvergents  maximum number of convergents to examine
388      * @param convergenceTest the test if the series has converged at a step
389      * @return the pair of last element of the series of convergents and a boolean
390      *         indicating if that element satisfies the specified convergent test
391      */
392     public static Pair<BigFraction, Boolean> convergent(double value, int maxConvergents,
393             ConvergenceTest convergenceTest) {
394         Pair<ConvergenceStep, Boolean> converged = ConvergentsIterator.convergent(value, maxConvergents,
395                 s -> convergenceTest.test(s.getNumerator(), s.getDenominator()));
396         return Pair.create(STEP_TO_FRACTION.apply(converged.getKey()), converged.getValue());
397     }
398 
399     /** {@inheritDoc} */
400     @Override
401     public double getReal() {
402         return doubleValue();
403     }
404 
405     /**
406      * <p>
407      * Creates a {@code BigFraction} instance with the 2 parts of a fraction
408      * Y/Z.
409      * </p>
410      *
411      * <p>
412      * Any negative signs are resolved to be on the numerator.
413      * </p>
414      *
415      * @param numerator
416      *            the numerator, for example the three in 'three sevenths'.
417      * @param denominator
418      *            the denominator, for example the seven in 'three sevenths'.
419      * @return a new fraction instance, with the numerator and denominator
420      *         reduced.
421      * @throws ArithmeticException
422      *             if the denominator is <code>zero</code>.
423      */
424     public static BigFraction getReducedFraction(final int numerator,
425                                                  final int denominator) {
426         if (numerator == 0) {
427             return ZERO; // normalize zero.
428         }
429 
430         return new BigFraction(numerator, denominator);
431     }
432 
433     /**
434      * <p>
435      * Returns the absolute value of this {@link BigFraction}.
436      * </p>
437      *
438      * @return the absolute value as a {@link BigFraction}.
439      */
440     public BigFraction abs() {
441         return (numerator.signum() == 1) ? this : negate();
442     }
443 
444     /** Check if a fraction is an integer.
445      * @return true of fraction is an integer
446      */
447     public boolean isInteger() {
448         return denominator.equals(BigInteger.ONE);
449     }
450 
451     /** Returns the signum function of this {@link BigFraction}.
452      * <p>
453      * The return value is -1 if the specified value is negative;
454      * 0 if the specified value is zero; and 1 if the specified value is positive.
455      * </p>
456      * @return the signum function of this {@link BigFraction}
457      * @since 1.7
458      */
459     public int signum() {
460         return numerator.signum();
461     }
462 
463     /**
464      * <p>
465      * Adds the value of this fraction to the passed {@link BigInteger},
466      * returning the result in reduced form.
467      * </p>
468      *
469      * @param bg
470      *            the {@link BigInteger} to add, must'nt be <code>null</code>.
471      * @return a {@code BigFraction} instance with the resulting values.
472      * @throws NullArgumentException
473      *             if the {@link BigInteger} is <code>null</code>.
474      */
475     public BigFraction add(final BigInteger bg) throws NullArgumentException {
476         MathUtils.checkNotNull(bg);
477 
478         if (numerator.signum() == 0) {
479             return new BigFraction(bg);
480         }
481         if (bg.signum() == 0) {
482             return this;
483         }
484 
485         return new BigFraction(numerator.add(denominator.multiply(bg)), denominator);
486     }
487 
488     /**
489      * <p>
490      * Adds the value of this fraction to the passed {@code integer}, returning
491      * the result in reduced form.
492      * </p>
493      *
494      * @param i
495      *            the {@code integer} to add.
496      * @return a {@code BigFraction} instance with the resulting values.
497      */
498     public BigFraction add(final int i) {
499         return add(BigInteger.valueOf(i));
500     }
501 
502     /**
503      * <p>
504      * Adds the value of this fraction to the passed {@code long}, returning
505      * the result in reduced form.
506      * </p>
507      *
508      * @param l
509      *            the {@code long} to add.
510      * @return a {@code BigFraction} instance with the resulting values.
511      */
512     public BigFraction add(final long l) {
513         return add(BigInteger.valueOf(l));
514     }
515 
516     /**
517      * <p>
518      * Adds the value of this fraction to another, returning the result in
519      * reduced form.
520      * </p>
521      *
522      * @param fraction
523      *            the {@link BigFraction} to add, must not be <code>null</code>.
524      * @return a {@link BigFraction} instance with the resulting values.
525      * @throws NullArgumentException if the {@link BigFraction} is {@code null}.
526      */
527     @Override
528     public BigFraction add(final BigFraction fraction) {
529         MathUtils.checkNotNull(fraction, LocalizedCoreFormats.FRACTION);
530         if (fraction.numerator.signum() == 0) {
531             return this;
532         }
533         if (numerator.signum() == 0) {
534             return fraction;
535         }
536 
537         BigInteger num;
538         BigInteger den;
539         if (denominator.equals(fraction.denominator)) {
540             num = numerator.add(fraction.numerator);
541             den = denominator;
542         } else {
543             num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator));
544             den = denominator.multiply(fraction.denominator);
545         }
546 
547         if (num.signum() == 0) {
548             return ZERO;
549         }
550 
551         return new BigFraction(num, den);
552 
553     }
554 
555     /**
556      * <p>
557      * Gets the fraction as a <code>BigDecimal</code>. This calculates the
558      * fraction as the numerator divided by denominator.
559      * </p>
560      *
561      * @return the fraction as a <code>BigDecimal</code>.
562      * @throws ArithmeticException
563      *             if the exact quotient does not have a terminating decimal
564      *             expansion.
565      * @see BigDecimal
566      */
567     public BigDecimal bigDecimalValue() {
568         return new BigDecimal(numerator).divide(new BigDecimal(denominator));
569     }
570 
571     /**
572      * <p>
573      * Gets the fraction as a <code>BigDecimal</code> following the passed
574      * rounding mode. This calculates the fraction as the numerator divided by
575      * denominator.
576      * </p>
577      *
578      * @param roundingMode
579      *            rounding mode to apply. see {@link BigDecimal} constants.
580      * @return the fraction as a <code>BigDecimal</code>.
581      * @throws IllegalArgumentException
582      *             if {@code roundingMode} does not represent a valid rounding
583      *             mode.
584      * @see BigDecimal
585      */
586     public BigDecimal bigDecimalValue(final RoundingMode roundingMode) {
587         return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode);
588     }
589 
590     /**
591      * <p>
592      * Gets the fraction as a <code>BigDecimal</code> following the passed scale
593      * and rounding mode. This calculates the fraction as the numerator divided
594      * by denominator.
595      * </p>
596      *
597      * @param scale
598      *            scale of the <code>BigDecimal</code> quotient to be returned.
599      *            see {@link BigDecimal} for more information.
600      * @param roundingMode
601      *            rounding mode to apply. see {@link BigDecimal} constants.
602      * @return the fraction as a <code>BigDecimal</code>.
603      * @see BigDecimal
604      */
605     public BigDecimal bigDecimalValue(final int scale, final RoundingMode roundingMode) {
606         return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode);
607     }
608 
609     /**
610      * <p>
611      * Compares this object to another based on size.
612      * </p>
613      *
614      * @param object
615      *            the object to compare to, must not be <code>null</code>.
616      * @return -1 if this is less than {@code object}, +1 if this is greater
617      *         than {@code object}, 0 if they are equal.
618      * @see java.lang.Comparable#compareTo(java.lang.Object)
619      */
620     @Override
621     public int compareTo(final BigFraction object) {
622         int lhsSigNum = numerator.signum();
623         int rhsSigNum = object.numerator.signum();
624 
625         if (lhsSigNum != rhsSigNum) {
626             return (lhsSigNum > rhsSigNum) ? 1 : -1;
627         }
628         if (lhsSigNum == 0) {
629             return 0;
630         }
631 
632         BigInteger nOd = numerator.multiply(object.denominator);
633         BigInteger dOn = denominator.multiply(object.numerator);
634         return nOd.compareTo(dOn);
635     }
636 
637     /**
638      * <p>
639      * Divide the value of this fraction by the passed {@code BigInteger},
640      * ie {@code this * 1 / bg}, returning the result in reduced form.
641      * </p>
642      *
643      * @param bg the {@code BigInteger} to divide by, must not be {@code null}
644      * @return a {@link BigFraction} instance with the resulting values
645      * @throws NullArgumentException if the {@code BigInteger} is {@code null}
646      * @throws MathRuntimeException if the fraction to divide by is zero
647      */
648     public BigFraction divide(final BigInteger bg) {
649         MathUtils.checkNotNull(bg);
650         if (bg.signum() == 0) {
651             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
652         }
653         if (numerator.signum() == 0) {
654             return ZERO;
655         }
656         return new BigFraction(numerator, denominator.multiply(bg));
657     }
658 
659     /**
660      * <p>
661      * Divide the value of this fraction by the passed {@code int}, ie
662      * {@code this * 1 / i}, returning the result in reduced form.
663      * </p>
664      *
665      * @param i the {@code int} to divide by
666      * @return a {@link BigFraction} instance with the resulting values
667      * @throws MathRuntimeException if the fraction to divide by is zero
668      */
669     public BigFraction divide(final int i) {
670         return divide(BigInteger.valueOf(i));
671     }
672 
673     /**
674      * <p>
675      * Divide the value of this fraction by the passed {@code long}, ie
676      * {@code this * 1 / l}, returning the result in reduced form.
677      * </p>
678      *
679      * @param l the {@code long} to divide by
680      * @return a {@link BigFraction} instance with the resulting values
681      * @throws MathRuntimeException if the fraction to divide by is zero
682      */
683     public BigFraction divide(final long l) {
684         return divide(BigInteger.valueOf(l));
685     }
686 
687     /**
688      * <p>
689      * Divide the value of this fraction by another, returning the result in
690      * reduced form.
691      * </p>
692      *
693      * @param fraction Fraction to divide by, must not be {@code null}.
694      * @return a {@link BigFraction} instance with the resulting values.
695      * @throws NullArgumentException if the {@code fraction} is {@code null}.
696      * @throws MathRuntimeException if the fraction to divide by is zero
697      */
698     @Override
699     public BigFraction divide(final BigFraction fraction) {
700         MathUtils.checkNotNull(fraction, LocalizedCoreFormats.FRACTION);
701         if (fraction.numerator.signum() == 0) {
702             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
703         }
704         if (numerator.signum() == 0) {
705             return ZERO;
706         }
707 
708         return multiply(fraction.reciprocal());
709     }
710 
711     /**
712      * <p>
713      * Gets the fraction as a {@code double}. This calculates the fraction as
714      * the numerator divided by denominator.
715      * </p>
716      *
717      * @return the fraction as a {@code double}
718      * @see java.lang.Number#doubleValue()
719      */
720     @Override
721     public double doubleValue() {
722         double result = numerator.doubleValue() / denominator.doubleValue();
723         if (Double.isInfinite(result) || Double.isNaN(result)) {
724             // Numerator and/or denominator must be out of range:
725             // Calculate how far to shift them to put them in range.
726             int shift = FastMath.max(numerator.bitLength(),
727                                      denominator.bitLength()) - FastMath.getExponent(Double.MAX_VALUE);
728             result = numerator.shiftRight(shift).doubleValue() /
729                 denominator.shiftRight(shift).doubleValue();
730         }
731         return result;
732     }
733 
734     /**
735      * <p>
736      * Test for the equality of two fractions. If the lowest term numerator and
737      * denominators are the same for both fractions, the two fractions are
738      * considered to be equal.
739      * </p>
740      *
741      * @param other
742      *            fraction to test for equality to this fraction, can be
743      *            <code>null</code>.
744      * @return true if two fractions are equal, false if object is
745      *         <code>null</code>, not an instance of {@link BigFraction}, or not
746      *         equal to this fraction instance.
747      * @see java.lang.Object#equals(java.lang.Object)
748      */
749     @Override
750     public boolean equals(final Object other) {
751         boolean ret = false;
752 
753         if (this == other) {
754             ret = true;
755         } else if (other instanceof BigFraction) {
756             BigFraction rhs = (BigFraction) other;
757             ret = numerator.equals(rhs.numerator) && denominator.equals(rhs.denominator);
758         }
759 
760         return ret;
761     }
762 
763     /**
764      * <p>
765      * Gets the fraction as a {@code float}. This calculates the fraction as
766      * the numerator divided by denominator.
767      * </p>
768      *
769      * @return the fraction as a {@code float}.
770      * @see java.lang.Number#floatValue()
771      */
772     @Override
773     public float floatValue() {
774         float result = numerator.floatValue() / denominator.floatValue();
775         if (Double.isNaN(result)) {
776             // Numerator and/or denominator must be out of range:
777             // Calculate how far to shift them to put them in range.
778             int shift = FastMath.max(numerator.bitLength(),
779                                      denominator.bitLength()) - FastMath.getExponent(Float.MAX_VALUE);
780             result = numerator.shiftRight(shift).floatValue() /
781                 denominator.shiftRight(shift).floatValue();
782         }
783         return result;
784     }
785 
786     /**
787      * {@link java.math.BigInteger} number least common multiple.
788      *
789      * @param i0 first number
790      * @param i1 second number
791      * @return Least Common Multiple of both numbers
792      * @since 3.1
793      */
794     private static BigInteger lcm(final BigInteger i0, final BigInteger i1) {
795       if (i0.signum() == 0 && i1.signum() == 0) {
796         return BigInteger.ZERO;
797       }
798       BigInteger a = i0.abs();
799       BigInteger b = i1.abs();
800       BigInteger gcd = i0.gcd(b);
801       return (a.multiply(b)).divide(gcd);
802     }
803 
804     /**
805      * Rational number greatest common divisor.
806      *
807      * @param s fraction.
808      * @return gcd(this, s).
809      * @since 3.1
810      */
811     public BigFraction gcd(BigFraction s) {
812       if (s.isZero()) {
813         return this;
814       }
815       if (this.isZero()) {
816         return s;
817       }
818       BigInteger p = numerator.gcd(s.numerator);
819       BigInteger q = lcm(denominator, s.denominator);
820       return new BigFraction(p, q);
821     }
822 
823     /**
824      * Rational number least common multiple.
825      *
826      * @param s fraction.
827      * @return lcm(this, s).
828      * @since 3.1
829      */
830     public BigFraction lcm(BigFraction s) {
831       if (s.isZero()) {
832         return ZERO;
833       }
834       if (this.isZero()) {
835         return ZERO;
836       }
837       return new BigFraction(lcm(numerator, s.numerator), denominator.gcd(s.denominator));
838     }
839 
840     /**
841      * <p>
842      * Access the denominator as a <code>BigInteger</code>.
843      * </p>
844      *
845      * @return the denominator as a <code>BigInteger</code>.
846      */
847     public BigInteger getDenominator() {
848         return denominator;
849     }
850 
851     /**
852      * <p>
853      * Access the denominator as a {@code int}.
854      * </p>
855      *
856      * @return the denominator as a {@code int}.
857      */
858     public int getDenominatorAsInt() {
859         return denominator.intValue();
860     }
861 
862     /**
863      * <p>
864      * Access the denominator as a {@code long}.
865      * </p>
866      *
867      * @return the denominator as a {@code long}.
868      */
869     public long getDenominatorAsLong() {
870         return denominator.longValue();
871     }
872 
873     /**
874      * <p>
875      * Access the numerator as a <code>BigInteger</code>.
876      * </p>
877      *
878      * @return the numerator as a <code>BigInteger</code>.
879      */
880     public BigInteger getNumerator() {
881         return numerator;
882     }
883 
884     /**
885      * <p>
886      * Access the numerator as a {@code int}.
887      * </p>
888      *
889      * @return the numerator as a {@code int}.
890      */
891     public int getNumeratorAsInt() {
892         return numerator.intValue();
893     }
894 
895     /**
896      * <p>
897      * Access the numerator as a {@code long}.
898      * </p>
899      *
900      * @return the numerator as a {@code long}.
901      */
902     public long getNumeratorAsLong() {
903         return numerator.longValue();
904     }
905 
906     /**
907      * <p>
908      * Gets a hashCode for the fraction.
909      * </p>
910      *
911      * @return a hash code value for this object.
912      * @see java.lang.Object#hashCode()
913      */
914     @Override
915     public int hashCode() {
916         return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode();
917     }
918 
919     /**
920      * <p>
921      * Gets the fraction as an {@code int}. This returns the whole number part
922      * of the fraction.
923      * </p>
924      *
925      * @return the whole number fraction part.
926      * @see java.lang.Number#intValue()
927      */
928     @Override
929     public int intValue() {
930         return numerator.divide(denominator).intValue();
931     }
932 
933     /**
934      * <p>
935      * Gets the fraction as a {@code long}. This returns the whole number part
936      * of the fraction.
937      * </p>
938      *
939      * @return the whole number fraction part.
940      * @see java.lang.Number#longValue()
941      */
942     @Override
943     public long longValue() {
944         return numerator.divide(denominator).longValue();
945     }
946 
947     /**
948      * <p>
949      * Multiplies the value of this fraction by the passed
950      * <code>BigInteger</code>, returning the result in reduced form.
951      * </p>
952      *
953      * @param bg the {@code BigInteger} to multiply by.
954      * @return a {@code BigFraction} instance with the resulting values.
955      * @throws NullArgumentException if {@code bg} is {@code null}.
956      */
957     public BigFraction multiply(final BigInteger bg) {
958         MathUtils.checkNotNull(bg);
959         if (numerator.signum() == 0 || bg.signum() == 0) {
960             return ZERO;
961         }
962         return new BigFraction(bg.multiply(numerator), denominator);
963     }
964 
965     /**
966      * <p>
967      * Multiply the value of this fraction by the passed {@code int}, returning
968      * the result in reduced form.
969      * </p>
970      *
971      * @param i
972      *            the {@code int} to multiply by.
973      * @return a {@link BigFraction} instance with the resulting values.
974      */
975     @Override
976     public BigFraction multiply(final int i) {
977         if (i == 0 || numerator.signum() == 0) {
978             return ZERO;
979         }
980 
981         return multiply(BigInteger.valueOf(i));
982     }
983 
984     /**
985      * <p>
986      * Multiply the value of this fraction by the passed {@code long},
987      * returning the result in reduced form.
988      * </p>
989      *
990      * @param l
991      *            the {@code long} to multiply by.
992      * @return a {@link BigFraction} instance with the resulting values.
993      */
994     public BigFraction multiply(final long l) {
995         if (l == 0 || numerator.signum() == 0) {
996             return ZERO;
997         }
998 
999         return multiply(BigInteger.valueOf(l));
1000     }
1001 
1002     /**
1003      * <p>
1004      * Multiplies the value of this fraction by another, returning the result in
1005      * reduced form.
1006      * </p>
1007      *
1008      * @param fraction Fraction to multiply by, must not be {@code null}.
1009      * @return a {@link BigFraction} instance with the resulting values.
1010      * @throws NullArgumentException if {@code fraction} is {@code null}.
1011      */
1012     @Override
1013     public BigFraction multiply(final BigFraction fraction) {
1014         MathUtils.checkNotNull(fraction, LocalizedCoreFormats.FRACTION);
1015         if (numerator.signum() == 0 ||
1016             fraction.numerator.signum() == 0) {
1017             return ZERO;
1018         }
1019         return new BigFraction(numerator.multiply(fraction.numerator),
1020                                denominator.multiply(fraction.denominator));
1021     }
1022 
1023     /**
1024      * <p>
1025      * Return the additive inverse of this fraction, returning the result in
1026      * reduced form.
1027      * </p>
1028      *
1029      * @return the negation of this fraction.
1030      */
1031     @Override
1032     public BigFraction negate() {
1033         return new BigFraction(numerator.negate(), denominator);
1034     }
1035 
1036     /**
1037      * <p>
1038      * Gets the fraction percentage as a {@code double}. This calculates the
1039      * fraction as the numerator divided by denominator multiplied by 100.
1040      * </p>
1041      *
1042      * @return the fraction percentage as a {@code double}.
1043      */
1044     public double percentageValue() {
1045         return multiply(ONE_HUNDRED).doubleValue();
1046     }
1047 
1048     /**
1049      * <p>
1050      * Returns a {@code BigFraction} whose value is
1051      * {@code (this<sup>exponent</sup>)}, returning the result in reduced form.
1052      * </p>
1053      *
1054      * @param exponent
1055      *            exponent to which this {@code BigFraction} is to be
1056      *            raised.
1057      * @return this<sup>exponent</sup>
1058      */
1059     public BigFraction pow(final int exponent) {
1060         if (exponent == 0) {
1061             return ONE;
1062         }
1063         if (numerator.signum() == 0) {
1064             return this;
1065         }
1066 
1067         if (exponent < 0) {
1068             return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent));
1069         }
1070         return new BigFraction(numerator.pow(exponent), denominator.pow(exponent));
1071     }
1072 
1073     /**
1074      * <p>
1075      * Returns a {@code BigFraction} whose value is
1076      * this<sup>exponent</sup>, returning the result in reduced form.
1077      * </p>
1078      *
1079      * @param exponent
1080      *            exponent to which this {@code BigFraction} is to be raised.
1081      * @return this<sup>exponent</sup> as a {@code BigFraction}.
1082      */
1083     public BigFraction pow(final long exponent) {
1084         if (exponent == 0) {
1085             return ONE;
1086         }
1087         if (numerator.signum() == 0) {
1088             return this;
1089         }
1090 
1091         if (exponent < 0) {
1092             return new BigFraction(ArithmeticUtils.pow(denominator, -exponent),
1093                                    ArithmeticUtils.pow(numerator,   -exponent));
1094         }
1095         return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
1096                                ArithmeticUtils.pow(denominator, exponent));
1097     }
1098 
1099     /**
1100      * <p>
1101      * Returns a {@code BigFraction} whose value is
1102      * this<sup>exponent</sup>, returning the result in reduced form.
1103      * </p>
1104      *
1105      * @param exponent
1106      *            exponent to which this {@code BigFraction} is to be raised.
1107      * @return this<sup>exponent</sup> as a {@code BigFraction}.
1108      */
1109     public BigFraction pow(final BigInteger exponent) {
1110         if (exponent.signum() == 0) {
1111             return ONE;
1112         }
1113         if (numerator.signum() == 0) {
1114             return this;
1115         }
1116 
1117         if (exponent.signum() == -1) {
1118             final BigInteger eNeg = exponent.negate();
1119             return new BigFraction(ArithmeticUtils.pow(denominator, eNeg),
1120                                    ArithmeticUtils.pow(numerator,   eNeg));
1121         }
1122         return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
1123                                ArithmeticUtils.pow(denominator, exponent));
1124     }
1125 
1126     /**
1127      * <p>
1128      * Returns a <code>double</code> whose value is
1129      * this<sup>exponent</sup>, returning the result in reduced form.
1130      * </p>
1131      *
1132      * @param exponent
1133      *            exponent to which this {@code BigFraction} is to be raised.
1134      * @return this<sup>exponent</sup>
1135      */
1136     public double pow(final double exponent) {
1137         return FastMath.pow(numerator.doubleValue(),   exponent) /
1138                FastMath.pow(denominator.doubleValue(), exponent);
1139     }
1140 
1141     /**
1142      * <p>
1143      * Return the multiplicative inverse of this fraction.
1144      * </p>
1145      *
1146      * @return the reciprocal fraction.
1147      */
1148     @Override
1149     public BigFraction reciprocal() {
1150         return new BigFraction(denominator, numerator);
1151     }
1152 
1153     /**
1154      * <p>
1155      * Reduce this {@code BigFraction} to its lowest terms.
1156      * </p>
1157      *
1158      * @return the reduced {@code BigFraction}. It doesn't change anything if
1159      *         the fraction can be reduced.
1160      */
1161     public BigFraction reduce() {
1162         final BigInteger gcd = numerator.gcd(denominator);
1163 
1164         if (BigInteger.ONE.compareTo(gcd) < 0) {
1165             return new BigFraction(numerator.divide(gcd), denominator.divide(gcd));
1166         } else {
1167             return this;
1168         }
1169     }
1170 
1171     /**
1172      * <p>
1173      * Subtracts the value of an {@link BigInteger} from the value of this
1174      * {@code BigFraction}, returning the result in reduced form.
1175      * </p>
1176      *
1177      * @param bg the {@link BigInteger} to subtract, cannot be {@code null}.
1178      * @return a {@code BigFraction} instance with the resulting values.
1179      * @throws NullArgumentException if the {@link BigInteger} is {@code null}.
1180      */
1181     public BigFraction subtract(final BigInteger bg) {
1182         MathUtils.checkNotNull(bg);
1183         if (bg.signum() == 0) {
1184             return this;
1185         }
1186         if (numerator.signum() == 0) {
1187             return new BigFraction(bg.negate());
1188         }
1189 
1190         return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator);
1191     }
1192 
1193     /**
1194      * <p>
1195      * Subtracts the value of an {@code integer} from the value of this
1196      * {@code BigFraction}, returning the result in reduced form.
1197      * </p>
1198      *
1199      * @param i the {@code integer} to subtract.
1200      * @return a {@code BigFraction} instance with the resulting values.
1201      */
1202     public BigFraction subtract(final int i) {
1203         return subtract(BigInteger.valueOf(i));
1204     }
1205 
1206     /**
1207      * <p>
1208      * Subtracts the value of a {@code long} from the value of this
1209      * {@code BigFraction}, returning the result in reduced form.
1210      * </p>
1211      *
1212      * @param l the {@code long} to subtract.
1213      * @return a {@code BigFraction} instance with the resulting values.
1214      */
1215     public BigFraction subtract(final long l) {
1216         return subtract(BigInteger.valueOf(l));
1217     }
1218 
1219     /**
1220      * <p>
1221      * Subtracts the value of another fraction from the value of this one,
1222      * returning the result in reduced form.
1223      * </p>
1224      *
1225      * @param fraction {@link BigFraction} to subtract, must not be {@code null}.
1226      * @return a {@link BigFraction} instance with the resulting values
1227      * @throws NullArgumentException if the {@code fraction} is {@code null}.
1228      */
1229     @Override
1230     public BigFraction subtract(final BigFraction fraction) {
1231         MathUtils.checkNotNull(fraction, LocalizedCoreFormats.FRACTION);
1232         if (fraction.numerator.signum() == 0) {
1233             return this;
1234         }
1235         if (numerator.signum() == 0) {
1236             return fraction.negate();
1237         }
1238 
1239         BigInteger num;
1240         BigInteger den;
1241         if (denominator.equals(fraction.denominator)) {
1242             num = numerator.subtract(fraction.numerator);
1243             den = denominator;
1244         } else {
1245             num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator));
1246             den = denominator.multiply(fraction.denominator);
1247         }
1248         return new BigFraction(num, den);
1249 
1250     }
1251 
1252     /**
1253      * <p>
1254      * Returns the <code>String</code> representing this fraction, ie
1255      * "num / dem" or just "num" if the denominator is one.
1256      * </p>
1257      *
1258      * @return a string representation of the fraction.
1259      * @see java.lang.Object#toString()
1260      */
1261     @Override
1262     public String toString() {
1263         if (BigInteger.ONE.equals(denominator)) {
1264             return numerator.toString();
1265         } else if (BigInteger.ZERO.equals(numerator)) {
1266             return "0";
1267         } else {
1268             return numerator + " / " + denominator;
1269         }
1270     }
1271 
1272     /** {@inheritDoc} */
1273     @Override
1274     public BigFractionField getField() {
1275         return BigFractionField.getInstance();
1276     }
1277 
1278 }