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    *      http://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  package org.apache.commons.numbers.fraction;
18  
19  import java.io.Serializable;
20  import org.apache.commons.numbers.core.ArithmeticUtils;
21  import org.apache.commons.numbers.core.NativeOperators;
22  
23  /**
24   * Representation of a rational number.
25   *
26   * <p>The number is expressed as the quotient {@code p/q} of two 32-bit integers,
27   * a numerator {@code p} and a non-zero denominator {@code q}.
28   *
29   * <p>This class is immutable.
30   *
31   * <a href="https://en.wikipedia.org/wiki/Rational_number">Rational number</a>
32   */
33  public final class Fraction
34      extends Number
35      implements Comparable<Fraction>,
36                 NativeOperators<Fraction>,
37                 Serializable {
38      /** A fraction representing "0". */
39      public static final Fraction ZERO = new Fraction(0);
40  
41      /** A fraction representing "1". */
42      public static final Fraction ONE = new Fraction(1);
43  
44      /** Serializable version identifier. */
45      private static final long serialVersionUID = 20190701L;
46  
47      /** The default epsilon used for convergence. */
48      private static final double DEFAULT_EPSILON = 1e-5;
49  
50      /** The default iterations used for convergence. */
51      private static final int DEFAULT_MAX_ITERATIONS = 100;
52  
53      /** Message for non-finite input double argument to factory constructors. */
54      private static final String NOT_FINITE = "Not finite: ";
55  
56      /** The overflow limit for conversion from a double (2^31). */
57      private static final long OVERFLOW = 1L << 31;
58  
59      /** The numerator of this fraction reduced to lowest terms. */
60      private final int numerator;
61  
62      /** The denominator of this fraction reduced to lowest terms. */
63      private final int denominator;
64  
65      /**
66       * Private constructor: Instances are created using factory methods.
67       *
68       * <p>This constructor should only be invoked when the fraction is known
69       * to be non-zero; otherwise use {@link #ZERO}. This avoids creating
70       * the zero representation {@code 0 / -1}.
71       *
72       * @param num Numerator.
73       * @param den Denominator.
74       * @throws ArithmeticException if the denominator is {@code zero}.
75       */
76      private Fraction(int num, int den) {
77          if (den == 0) {
78              throw new FractionException(FractionException.ERROR_ZERO_DENOMINATOR);
79          }
80  
81          if (num == den) {
82              numerator = 1;
83              denominator = 1;
84          } else {
85              // Reduce numerator (p) and denominator (q) by greatest common divisor.
86              final int p;
87              final int q;
88  
89              // If num and den are both 2^-31, or if one is 0 and the other is 2^-31,
90              // the calculation of the gcd below will fail. Ensure that this does not
91              // happen by dividing both by 2 in case both are even.
92              if (((num | den) & 1) == 0) {
93                  p = num >> 1;
94                  q = den >> 1;
95              } else {
96                  p = num;
97                  q = den;
98              }
99  
100             // Will not throw.
101             // Cannot return 0 as gcd(0, 0) has been eliminated.
102             final int d = ArithmeticUtils.gcd(p, q);
103             numerator = p / d;
104             denominator = q / d;
105         }
106     }
107 
108     /**
109      * Private constructor: Instances are created using factory methods.
110      *
111      * <p>This sets the denominator to 1.
112      *
113      * @param num Numerator.
114      */
115     private Fraction(int num) {
116         numerator = num;
117         denominator = 1;
118     }
119 
120     /**
121      * Create a fraction given the double value and either the maximum error
122      * allowed or the maximum number of denominator digits.
123      *
124      * <p>
125      * NOTE: This constructor is called with:
126      * <ul>
127      *  <li>EITHER a valid epsilon value and the maxDenominator set to
128      *      Integer.MAX_VALUE (that way the maxDenominator has no effect)</li>
129      *  <li>OR a valid maxDenominator value and the epsilon value set to
130      *      zero (that way epsilon only has effect if there is an exact
131      *      match before the maxDenominator value is reached).</li>
132      * </ul>
133      * <p>
134      * It has been done this way so that the same code can be reused for
135      * both scenarios. However this could be confusing to users if it
136      * were part of the public API and this method should therefore remain
137      * PRIVATE.
138      * </p>
139      *
140      * <p>
141      * See JIRA issue ticket MATH-181 for more details:
142      *     https://issues.apache.org/jira/browse/MATH-181
143      * </p>
144      *
145      * <p>
146      * Warning: This conversion assumes the value is not zero.
147      * </p>
148      *
149      * @param value Value to convert to a fraction. Must not be zero.
150      * @param epsilon Maximum error allowed.
151      * The resulting fraction is within {@code epsilon} of {@code value},
152      * in absolute terms.
153      * @param maxDenominator Maximum denominator value allowed.
154      * @param maxIterations Maximum number of convergents.
155      * @throws IllegalArgumentException if the given {@code value} is NaN or infinite.
156      * @throws ArithmeticException if the continued fraction failed to converge.
157      */
158     private Fraction(final double value,
159                      final double epsilon,
160                      final int maxDenominator,
161                      final int maxIterations) {
162         if (!Double.isFinite(value)) {
163             throw new IllegalArgumentException(NOT_FINITE + value);
164         }
165 
166         // Remove sign, this is restored at the end.
167         // (Assumes the value is not zero and thus signum(value) is not zero).
168         final double absValue = Math.abs(value);
169         double r0 = absValue;
170         long a0 = (long) Math.floor(r0);
171         if (a0 > OVERFLOW) {
172             throw new FractionException(FractionException.ERROR_CONVERSION_OVERFLOW, value, a0, 1);
173         }
174 
175         // check for (almost) integer arguments, which should not go to iterations.
176         if (r0 - a0 <= epsilon) {
177             int num = (int) a0;
178             int den = 1;
179             // Restore the sign.
180             if (Math.signum(num) != Math.signum(value)) {
181                 if (num == Integer.MIN_VALUE) {
182                     den = -den;
183                 } else {
184                     num = -num;
185                 }
186             }
187             this.numerator = num;
188             this.denominator = den;
189             return;
190         }
191 
192         // Support 2^31 as maximum denominator.
193         // This is negative as an integer so convert to long.
194         final long maxDen = Math.abs((long) maxDenominator);
195 
196         long p0 = 1;
197         long q0 = 0;
198         long p1 = a0;
199         long q1 = 1;
200 
201         long p2;
202         long q2;
203 
204         int n = 0;
205         boolean stop = false;
206         do {
207             ++n;
208             final double r1 = 1.0 / (r0 - a0);
209             final long a1 = (long) Math.floor(r1);
210             p2 = (a1 * p1) + p0;
211             q2 = (a1 * q1) + q0;
212 
213             if (Long.compareUnsigned(p2, OVERFLOW) > 0 ||
214                 Long.compareUnsigned(q2, OVERFLOW) > 0) {
215                 // In maxDenominator mode, fall-back to the previous valid fraction.
216                 if (epsilon == 0.0) {
217                     p2 = p1;
218                     q2 = q1;
219                     break;
220                 }
221                 throw new FractionException(FractionException.ERROR_CONVERSION_OVERFLOW, value, p2, q2);
222             }
223 
224             final double convergent = (double) p2 / q2;
225             if (n < maxIterations &&
226                 Math.abs(convergent - absValue) > epsilon &&
227                 q2 < maxDen) {
228                 p0 = p1;
229                 p1 = p2;
230                 q0 = q1;
231                 q1 = q2;
232                 a0 = a1;
233                 r0 = r1;
234             } else {
235                 stop = true;
236             }
237         } while (!stop);
238 
239         if (n >= maxIterations) {
240             throw new FractionException(FractionException.ERROR_CONVERSION, value, maxIterations);
241         }
242 
243         // Use p2 / q2 or p1 / q1 if q2 has grown too large in maxDenominator mode
244         // Note: Conversion of long 2^31 to an integer will create a negative. This could
245         // be either the numerator or denominator. This is handled by restoring the sign.
246         int num;
247         int den;
248         if (q2 <= maxDen) {
249             num = (int) p2;
250             den = (int) q2;
251         } else {
252             num = (int) p1;
253             den = (int) q1;
254         }
255 
256         // Restore the sign.
257         if (Math.signum(num) * Math.signum(den) != Math.signum(value)) {
258             if (num == Integer.MIN_VALUE) {
259                 den = -den;
260             } else {
261                 num = -num;
262             }
263         }
264 
265         this.numerator = num;
266         this.denominator = den;
267     }
268 
269     /**
270      * Create a fraction given the double value.
271      *
272      * @param value Value to convert to a fraction.
273      * @throws IllegalArgumentException if the given {@code value} is NaN or infinite.
274      * @throws ArithmeticException if the continued fraction failed to converge.
275      * @return a new instance.
276      */
277     public static Fraction from(final double value) {
278         return from(value, DEFAULT_EPSILON, DEFAULT_MAX_ITERATIONS);
279     }
280 
281     /**
282      * Create a fraction given the double value and maximum error allowed.
283      *
284      * <p>
285      * References:
286      * <ul>
287      * <li><a href="https://mathworld.wolfram.com/ContinuedFraction.html">
288      * Continued Fraction</a> equations (11) and (22)-(26)</li>
289      * </ul>
290      *
291      * @param value Value to convert to a fraction.
292      * @param epsilon Maximum error allowed. The resulting fraction is within
293      * {@code epsilon} of {@code value}, in absolute terms.
294      * @param maxIterations Maximum number of convergents.
295      * @throws IllegalArgumentException if the given {@code value} is NaN or infinite;
296      * {@code epsilon} is not positive; or {@code maxIterations < 1}.
297      * @throws ArithmeticException if the continued fraction failed to converge.
298      * @return a new instance.
299      */
300     public static Fraction from(final double value,
301                                 final double epsilon,
302                                 final int maxIterations) {
303         if (value == 0) {
304             return ZERO;
305         }
306         if (maxIterations < 1) {
307             throw new IllegalArgumentException("Max iterations must be strictly positive: " + maxIterations);
308         }
309         if (epsilon >= 0) {
310             return new Fraction(value, epsilon, Integer.MIN_VALUE, maxIterations);
311         }
312         throw new IllegalArgumentException("Epsilon must be positive: " + maxIterations);
313     }
314 
315     /**
316      * Create a fraction given the double value and maximum denominator.
317      *
318      * <p>
319      * References:
320      * <ul>
321      * <li><a href="https://mathworld.wolfram.com/ContinuedFraction.html">
322      * Continued Fraction</a> equations (11) and (22)-(26)</li>
323      * </ul>
324      *
325      * <p>Note: The magnitude of the {@code maxDenominator} is used allowing use of
326      * {@link Integer#MIN_VALUE} for a supported maximum denominator of 2<sup>31</sup>.
327      *
328      * @param value Value to convert to a fraction.
329      * @param maxDenominator Maximum allowed value for denominator.
330      * @throws IllegalArgumentException if the given {@code value} is NaN or infinite
331      * or {@code maxDenominator} is zero.
332      * @throws ArithmeticException if the continued fraction failed to converge.
333      * @return a new instance.
334      */
335     public static Fraction from(final double value,
336                                 final int maxDenominator) {
337         if (value == 0) {
338             return ZERO;
339         }
340         if (maxDenominator == 0) {
341             // Re-use the zero denominator message
342             throw new IllegalArgumentException(FractionException.ERROR_ZERO_DENOMINATOR);
343         }
344         return new Fraction(value, 0, maxDenominator, DEFAULT_MAX_ITERATIONS);
345     }
346 
347     /**
348      * Create a fraction given the numerator. The denominator is {@code 1}.
349      *
350      * @param num Numerator.
351      * @return a new instance.
352      */
353     public static Fraction of(final int num) {
354         if (num == 0) {
355             return ZERO;
356         }
357         return new Fraction(num);
358     }
359 
360     /**
361      * Create a fraction given the numerator and denominator.
362      * The fraction is reduced to lowest terms.
363      *
364      * @param num Numerator.
365      * @param den Denominator.
366      * @throws ArithmeticException if the denominator is {@code zero}.
367      * @return a new instance.
368      */
369     public static Fraction of(final int num, final int den) {
370         if (num == 0) {
371             return ZERO;
372         }
373         return new Fraction(num, den);
374     }
375 
376     /**
377      * Returns a {@code Fraction} instance representing the specified string {@code s}.
378      *
379      * <p>If {@code s} is {@code null}, then a {@code NullPointerException} is thrown.
380      *
381      * <p>The string must be in a format compatible with that produced by
382      * {@link #toString() Fraction.toString()}.
383      * The format expects an integer optionally followed by a {@code '/'} character and
384      * and second integer. Leading and trailing spaces are allowed around each numeric part.
385      * Each numeric part is parsed using {@link Integer#parseInt(String)}. The parts
386      * are interpreted as the numerator and optional denominator of the fraction. If absent
387      * the denominator is assumed to be "1".
388      *
389      * <p>Examples of valid strings and the equivalent {@code Fraction} are shown below:
390      *
391      * <pre>
392      * "0"                 = Fraction.of(0)
393      * "42"                = Fraction.of(42)
394      * "0 / 1"             = Fraction.of(0, 1)
395      * "1 / 3"             = Fraction.of(1, 3)
396      * "-4 / 13"           = Fraction.of(-4, 13)</pre>
397      *
398      * <p>Note: The fraction is returned in reduced form and the numerator and denominator
399      * may not match the values in the input string. For this reason the result of
400      * {@code Fraction.parse(s).toString().equals(s)} may not be {@code true}.
401      *
402      * @param s String representation.
403      * @return an instance.
404      * @throws NullPointerException if the string is null.
405      * @throws NumberFormatException if the string does not contain a parsable fraction.
406      * @see Integer#parseInt(String)
407      * @see #toString()
408      */
409     public static Fraction parse(String s) {
410         final String stripped = s.replace(",", "");
411         final int slashLoc = stripped.indexOf('/');
412         // if no slash, parse as single number
413         if (slashLoc == -1) {
414             return of(Integer.parseInt(stripped.trim()));
415         }
416         final int num = Integer.parseInt(stripped.substring(0, slashLoc).trim());
417         final int denom = Integer.parseInt(stripped.substring(slashLoc + 1).trim());
418         return of(num, denom);
419     }
420 
421     @Override
422     public Fraction zero() {
423         return ZERO;
424     }
425 
426     /**
427      * {@inheritDoc}
428      *
429      * @since 1.2
430      */
431     @Override
432     public boolean isZero() {
433         return numerator == 0;
434     }
435 
436     @Override
437     public Fraction one() {
438         return ONE;
439     }
440 
441     /**
442      * {@inheritDoc}
443      *
444      * @since 1.2
445      */
446     @Override
447     public boolean isOne() {
448         return numerator == denominator;
449     }
450 
451     /**
452      * Access the numerator as an {@code int}.
453      *
454      * @return the numerator as an {@code int}.
455      */
456     public int getNumerator() {
457         return numerator;
458     }
459 
460     /**
461      * Access the denominator as an {@code int}.
462      *
463      * @return the denominator as an {@code int}.
464      */
465     public int getDenominator() {
466         return denominator;
467     }
468 
469     /**
470      * Retrieves the sign of this fraction.
471      *
472      * @return -1 if the value is strictly negative, 1 if it is strictly
473      * positive, 0 if it is 0.
474      */
475     public int signum() {
476         return Integer.signum(numerator) * Integer.signum(denominator);
477     }
478 
479     /**
480      * Returns the absolute value of this fraction.
481      *
482      * @return the absolute value.
483      */
484     public Fraction abs() {
485         return signum() >= 0 ?
486             this :
487             negate();
488     }
489 
490     @Override
491     public Fraction negate() {
492         return numerator == Integer.MIN_VALUE ?
493             new Fraction(numerator, -denominator) :
494             new Fraction(-numerator, denominator);
495     }
496 
497     /**
498      * {@inheritDoc}
499      *
500      * <p>Raises an exception if the fraction is equal to zero.
501      *
502      * @throws ArithmeticException if the current numerator is {@code zero}
503      */
504     @Override
505     public Fraction reciprocal() {
506         return new Fraction(denominator, numerator);
507     }
508 
509     /**
510      * Returns the {@code double} value closest to this fraction.
511      * This calculates the fraction as numerator divided by denominator.
512      *
513      * @return the fraction as a {@code double}.
514      */
515     @Override
516     public double doubleValue() {
517         return numerator / (double) denominator;
518     }
519 
520     /**
521      * Returns the {@code float} value closest to this fraction.
522      * This calculates the fraction as numerator divided by denominator.
523      *
524      * @return the fraction as a {@code float}.
525      */
526     @Override
527     public float floatValue() {
528         return (float) doubleValue();
529     }
530 
531     /**
532      * Returns the whole number part of the fraction.
533      *
534      * @return the largest {@code int} value that is not larger than this fraction.
535      */
536     @Override
537     public int intValue() {
538         // Note: numerator / denominator fails for Integer.MIN_VALUE / -1.
539         // Casting the double value handles this case.
540         return (int) doubleValue();
541     }
542 
543     /**
544      * Returns the whole number part of the fraction.
545      *
546      * @return the largest {@code long} value that is not larger than this fraction.
547      */
548     @Override
549     public long longValue() {
550         return (long) numerator / denominator;
551     }
552 
553     /**
554      * Adds the specified {@code value} to this fraction, returning
555      * the result in reduced form.
556      *
557      * @param value Value to add.
558      * @return {@code this + value}.
559      * @throws ArithmeticException if the resulting numerator
560      * cannot be represented in an {@code int}.
561      */
562     public Fraction add(final int value) {
563         if (value == 0) {
564             return this;
565         }
566         if (isZero()) {
567             return new Fraction(value);
568         }
569         // Convert to numerator with same effective denominator
570         final long num = (long) value * denominator;
571         return of(Math.toIntExact(numerator + num), denominator);
572     }
573 
574     /**
575      * Adds the specified {@code value} to this fraction, returning
576      * the result in reduced form.
577      *
578      * @param value Value to add.
579      * @return {@code this + value}.
580      * @throws ArithmeticException if the resulting numerator or denominator
581      * cannot be represented in an {@code int}.
582      */
583     @Override
584     public Fraction add(Fraction value) {
585         return addSub(value, true /* add */);
586     }
587 
588     /**
589      * Subtracts the specified {@code value} from this fraction, returning
590      * the result in reduced form.
591      *
592      * @param value Value to subtract.
593      * @return {@code this - value}.
594      * @throws ArithmeticException if the resulting numerator
595      * cannot be represented in an {@code int}.
596      */
597     public Fraction subtract(final int value) {
598         if (value == 0) {
599             return this;
600         }
601         if (isZero()) {
602             // Special case for min value
603             return value == Integer.MIN_VALUE ?
604                 new Fraction(Integer.MIN_VALUE, -1) :
605                 new Fraction(-value);
606         }
607         // Convert to numerator with same effective denominator
608         final long num = (long) value * denominator;
609         return of(Math.toIntExact(numerator - num), denominator);
610     }
611 
612     /**
613      * Subtracts the specified {@code value} from this fraction, returning
614      * the result in reduced form.
615      *
616      * @param value Value to subtract.
617      * @return {@code this - value}.
618      * @throws ArithmeticException if the resulting numerator or denominator
619      * cannot be represented in an {@code int}.
620      */
621     @Override
622     public Fraction subtract(Fraction value) {
623         return addSub(value, false /* subtract */);
624     }
625 
626     /**
627      * Implements add and subtract using algorithm described in Knuth 4.5.1.
628      *
629      * @param value Fraction to add or subtract.
630      * @param isAdd Whether the operation is "add" or "subtract".
631      * @return a new instance.
632      * @throws ArithmeticException if the resulting numerator or denominator
633      * cannot be represented in an {@code int}.
634      */
635     private Fraction addSub(Fraction value, boolean isAdd) {
636         if (value.isZero()) {
637             return this;
638         }
639         // Zero is identity for addition.
640         if (isZero()) {
641             return isAdd ? value : value.negate();
642         }
643 
644         /*
645          * Let the two fractions be u/u' and v/v', and d1 = gcd(u', v').
646          * First, compute t, defined as:
647          *
648          * t = u(v'/d1) +/- v(u'/d1)
649          */
650         final int d1 = ArithmeticUtils.gcd(denominator, value.denominator);
651         final long uvp = (long) numerator * (value.denominator / d1);
652         final long upv = (long) value.numerator * (denominator / d1);
653 
654         /*
655          * The largest possible absolute value of a product of two ints is 2^62,
656          * which can only happen as a result of -2^31 * -2^31 = 2^62, so a
657          * product of -2^62 is not possible. It follows that (uvp - upv) cannot
658          * overflow, and (uvp + upv) could only overflow if uvp = upv = 2^62.
659          * But for this to happen, the terms u, v, v'/d1 and u'/d1 would all
660          * have to be -2^31, which is not possible because v'/d1 and u'/d1
661          * are necessarily coprime.
662          */
663         final long t = isAdd ? uvp + upv : uvp - upv;
664 
665         /*
666          * Because u is coprime to u' and v is coprime to v', t is necessarily
667          * coprime to both v'/d1 and u'/d1. However, it might have a common
668          * factor with d1.
669          */
670         final long d2 = ArithmeticUtils.gcd(t, d1);
671         // result is (t/d2) / (u'/d1)(v'/d2)
672         return of(Math.toIntExact(t / d2),
673                   Math.multiplyExact(denominator / d1,
674                                      value.denominator / (int) d2));
675     }
676 
677     /**
678      * Multiply this fraction by the passed {@code value}, returning
679      * the result in reduced form.
680      *
681      * @param value Value to multiply by.
682      * @return {@code this * value}.
683      * @throws ArithmeticException if the resulting numerator
684      * cannot be represented in an {@code int}.
685      */
686     @Override
687     public Fraction multiply(final int value) {
688         if (value == 0 || isZero()) {
689             return ZERO;
690         }
691 
692         // knuth 4.5.1
693         // Make sure we don't overflow unless the result *must* overflow.
694         // (see multiply(Fraction) using value / 1 as the argument).
695         final int d2 = ArithmeticUtils.gcd(value, denominator);
696         return new Fraction(Math.multiplyExact(numerator, value / d2),
697                             denominator / d2);
698     }
699 
700     /**
701      * Multiply this fraction by the passed {@code value}, returning
702      * the result in reduced form.
703      *
704      * @param value Value to multiply by.
705      * @return {@code this * value}.
706      * @throws ArithmeticException if the resulting numerator or denominator
707      * cannot be represented in an {@code int}.
708      */
709     @Override
710     public Fraction multiply(Fraction value) {
711         if (value.isZero() || isZero()) {
712             return ZERO;
713         }
714         return multiply(value.numerator, value.denominator);
715     }
716 
717     /**
718      * Multiply this fraction by the passed fraction decomposed into a numerator and
719      * denominator, returning the result in reduced form.
720      *
721      * <p>This is a utility method to be used by multiply and divide. The decomposed
722      * fraction arguments and this fraction are not checked for zero.
723      *
724      * @param num Fraction numerator.
725      * @param den Fraction denominator.
726      * @return {@code this * num / den}.
727      * @throws ArithmeticException if the resulting numerator or denominator cannot
728      * be represented in an {@code int}.
729      */
730     private Fraction multiply(int num, int den) {
731         // knuth 4.5.1
732         // Make sure we don't overflow unless the result *must* overflow.
733         final int d1 = ArithmeticUtils.gcd(numerator, den);
734         final int d2 = ArithmeticUtils.gcd(num, denominator);
735         return new Fraction(Math.multiplyExact(numerator / d1, num / d2),
736                             Math.multiplyExact(denominator / d2, den / d1));
737     }
738 
739     /**
740      * Divide this fraction by the passed {@code value}, returning
741      * the result in reduced form.
742      *
743      * @param value Value to divide by
744      * @return {@code this / value}.
745      * @throws ArithmeticException if the value to divide by is zero
746      * or if the resulting numerator or denominator cannot be represented
747      * by an {@code int}.
748      */
749     public Fraction divide(final int value) {
750         if (value == 0) {
751             throw new FractionException(FractionException.ERROR_DIVIDE_BY_ZERO);
752         }
753         if (isZero()) {
754             return ZERO;
755         }
756         // Multiply by reciprocal
757 
758         // knuth 4.5.1
759         // Make sure we don't overflow unless the result *must* overflow.
760         // (see multiply(Fraction) using 1 / value as the argument).
761         final int d1 = ArithmeticUtils.gcd(numerator, value);
762         return new Fraction(numerator / d1,
763                             Math.multiplyExact(denominator, value / d1));
764     }
765 
766     /**
767      * Divide this fraction by the passed {@code value}, returning
768      * the result in reduced form.
769      *
770      * @param value Value to divide by
771      * @return {@code this / value}.
772      * @throws ArithmeticException if the value to divide by is zero
773      * or if the resulting numerator or denominator cannot be represented
774      * by an {@code int}.
775      */
776     @Override
777     public Fraction divide(Fraction value) {
778         if (value.isZero()) {
779             throw new FractionException(FractionException.ERROR_DIVIDE_BY_ZERO);
780         }
781         if (isZero()) {
782             return ZERO;
783         }
784         // Multiply by reciprocal
785         return multiply(value.denominator, value.numerator);
786     }
787 
788     /**
789      * Returns a {@code Fraction} whose value is
790      * <code>this<sup>exponent</sup></code>, returning the result in reduced form.
791      *
792      * @param exponent exponent to which this {@code Fraction} is to be raised.
793      * @return <code>this<sup>exponent</sup></code>.
794      * @throws ArithmeticException if the intermediate result would overflow.
795      */
796     @Override
797     public Fraction pow(final int exponent) {
798         if (exponent == 1) {
799             return this;
800         }
801         if (exponent == 0) {
802             return ONE;
803         }
804         if (isZero()) {
805             if (exponent < 0) {
806                 throw new FractionException(FractionException.ERROR_ZERO_DENOMINATOR);
807             }
808             return ZERO;
809         }
810         if (exponent > 0) {
811             return new Fraction(ArithmeticUtils.pow(numerator, exponent),
812                                 ArithmeticUtils.pow(denominator, exponent));
813         }
814         if (exponent == -1) {
815             return this.reciprocal();
816         }
817         if (exponent == Integer.MIN_VALUE) {
818             // MIN_VALUE can't be negated
819             return new Fraction(ArithmeticUtils.pow(denominator, Integer.MAX_VALUE) * denominator,
820                                 ArithmeticUtils.pow(numerator, Integer.MAX_VALUE) * numerator);
821         }
822         return new Fraction(ArithmeticUtils.pow(denominator, -exponent),
823                             ArithmeticUtils.pow(numerator, -exponent));
824     }
825 
826     /**
827      * Returns the {@code String} representing this fraction.
828      * Uses:
829      * <ul>
830      *  <li>{@code "0"} if {@code numerator} is zero.</li>
831      *  <li>{@code "numerator"} if {@code denominator} is one.</li>
832      *  <li>{@code "numerator / denominator"} for all other cases.</li>
833      * </ul>
834      *
835      * @return a string representation of the fraction.
836      */
837     @Override
838     public String toString() {
839         final String str;
840         if (isZero()) {
841             str = "0";
842         } else if (denominator == 1) {
843             str = Integer.toString(numerator);
844         } else {
845             str = numerator + " / " + denominator;
846         }
847         return str;
848     }
849 
850     /**
851      * Compares this object with the specified object for order using the signed magnitude.
852      *
853      * @param other {@inheritDoc}
854      * @return {@inheritDoc}
855      */
856     @Override
857     public int compareTo(Fraction other) {
858         // Compute the sign of each part
859         final int lns = Integer.signum(numerator);
860         final int lds = Integer.signum(denominator);
861         final int rns = Integer.signum(other.numerator);
862         final int rds = Integer.signum(other.denominator);
863 
864         final int lhsSigNum = lns * lds;
865         final int rhsSigNum = rns * rds;
866 
867         if (lhsSigNum != rhsSigNum) {
868             return (lhsSigNum > rhsSigNum) ? 1 : -1;
869         }
870         // Same sign.
871         // Avoid a multiply if both fractions are zero
872         if (lhsSigNum == 0) {
873             return 0;
874         }
875         // Compare absolute magnitude.
876         // Multiplication by the signum is equal to the absolute.
877         final long nOd = ((long) numerator) * lns * other.denominator * rds;
878         final long dOn = ((long) denominator) * lds * other.numerator * rns;
879         return lhsSigNum > 0 ?
880             Long.compare(nOd, dOn) :
881             Long.compare(dOn, nOd);
882     }
883 
884     /**
885      * Test for equality with another object. If the other object is a {@code Fraction} then a
886      * comparison is made of the sign and magnitude; otherwise {@code false} is returned.
887      *
888      * @param other {@inheritDoc}
889      * @return {@inheritDoc}
890      */
891     @Override
892     public boolean equals(Object other) {
893         if (this == other) {
894             return true;
895         }
896 
897         if (other instanceof Fraction) {
898             // Since fractions are always in lowest terms, numerators and
899             // denominators can be compared directly for equality.
900             final Fraction rhs = (Fraction) other;
901             if (signum() == rhs.signum()) {
902                 return Math.abs(numerator) == Math.abs(rhs.numerator) &&
903                        Math.abs(denominator) == Math.abs(rhs.denominator);
904             }
905         }
906 
907         return false;
908     }
909 
910     @Override
911     public int hashCode() {
912         // Incorporate the sign and absolute values of the numerator and denominator.
913         // Equivalent to:
914         // int hash = 1;
915         // hash = 31 * hash + Math.abs(numerator);
916         // hash = 31 * hash + Math.abs(denominator);
917         // hash = hash * signum()
918         // Note: x * Integer.signum(x) == Math.abs(x).
919         final int numS = Integer.signum(numerator);
920         final int denS = Integer.signum(denominator);
921         return (31 * (31 + numerator * numS) + denominator * denS) * numS * denS;
922     }
923 }