Fraction.java

  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. import java.io.Serializable;
  19. import org.apache.commons.numbers.core.ArithmeticUtils;
  20. import org.apache.commons.numbers.core.NativeOperators;

  21. /**
  22.  * Representation of a rational number.
  23.  *
  24.  * <p>The number is expressed as the quotient {@code p/q} of two 32-bit integers,
  25.  * a numerator {@code p} and a non-zero denominator {@code q}.
  26.  *
  27.  * <p>This class is immutable.
  28.  *
  29.  * <a href="https://en.wikipedia.org/wiki/Rational_number">Rational number</a>
  30.  */
  31. public final class Fraction
  32.     extends Number
  33.     implements Comparable<Fraction>,
  34.                NativeOperators<Fraction>,
  35.                Serializable {
  36.     /** A fraction representing "0". */
  37.     public static final Fraction ZERO = new Fraction(0);

  38.     /** A fraction representing "1". */
  39.     public static final Fraction ONE = new Fraction(1);

  40.     /** Serializable version identifier. */
  41.     private static final long serialVersionUID = 20190701L;

  42.     /** The default epsilon used for convergence. */
  43.     private static final double DEFAULT_EPSILON = 1e-5;

  44.     /** The default iterations used for convergence. */
  45.     private static final int DEFAULT_MAX_ITERATIONS = 100;

  46.     /** Message for non-finite input double argument to factory constructors. */
  47.     private static final String NOT_FINITE = "Not finite: ";

  48.     /** The overflow limit for conversion from a double (2^31). */
  49.     private static final long OVERFLOW = 1L << 31;

  50.     /** The numerator of this fraction reduced to lowest terms. */
  51.     private final int numerator;

  52.     /** The denominator of this fraction reduced to lowest terms. */
  53.     private final int denominator;

  54.     /**
  55.      * Private constructor: Instances are created using factory methods.
  56.      *
  57.      * <p>This constructor should only be invoked when the fraction is known
  58.      * to be non-zero; otherwise use {@link #ZERO}. This avoids creating
  59.      * the zero representation {@code 0 / -1}.
  60.      *
  61.      * @param num Numerator.
  62.      * @param den Denominator.
  63.      * @throws ArithmeticException if the denominator is {@code zero}.
  64.      */
  65.     private Fraction(int num, int den) {
  66.         if (den == 0) {
  67.             throw new FractionException(FractionException.ERROR_ZERO_DENOMINATOR);
  68.         }

  69.         if (num == den) {
  70.             numerator = 1;
  71.             denominator = 1;
  72.         } else {
  73.             // Reduce numerator (p) and denominator (q) by greatest common divisor.
  74.             int p;
  75.             int q;

  76.             // If num and den are both 2^-31, or if one is 0 and the other is 2^-31,
  77.             // the calculation of the gcd below will fail. Ensure that this does not
  78.             // happen by dividing both by 2 in case both are even.
  79.             if (((num | den) & 1) == 0) {
  80.                 p = num >> 1;
  81.                 q = den >> 1;
  82.             } else {
  83.                 p = num;
  84.                 q = den;
  85.             }

  86.             // Will not throw.
  87.             // Cannot return 0 as gcd(0, 0) has been eliminated.
  88.             final int d = ArithmeticUtils.gcd(p, q);
  89.             numerator = p / d;
  90.             denominator = q / d;
  91.         }
  92.     }

  93.     /**
  94.      * Private constructor: Instances are created using factory methods.
  95.      *
  96.      * <p>This sets the denominator to 1.
  97.      *
  98.      * @param num Numerator.
  99.      */
  100.     private Fraction(int num) {
  101.         numerator = num;
  102.         denominator = 1;
  103.     }

  104.     /**
  105.      * Create a fraction given the double value and either the maximum error
  106.      * allowed or the maximum number of denominator digits.
  107.      *
  108.      * <p>
  109.      * NOTE: This constructor is called with:
  110.      * <ul>
  111.      *  <li>EITHER a valid epsilon value and the maxDenominator set to
  112.      *      Integer.MAX_VALUE (that way the maxDenominator has no effect)
  113.      *  <li>OR a valid maxDenominator value and the epsilon value set to
  114.      *      zero (that way epsilon only has effect if there is an exact
  115.      *      match before the maxDenominator value is reached).
  116.      * </ul>
  117.      * <p>
  118.      * It has been done this way so that the same code can be reused for
  119.      * both scenarios. However this could be confusing to users if it
  120.      * were part of the public API and this method should therefore remain
  121.      * PRIVATE.
  122.      * </p>
  123.      *
  124.      * <p>
  125.      * See JIRA issue ticket MATH-181 for more details:
  126.      *     https://issues.apache.org/jira/browse/MATH-181
  127.      * </p>
  128.      *
  129.      * <p>
  130.      * Warning: This conversion assumes the value is not zero.
  131.      * </p>
  132.      *
  133.      * @param value Value to convert to a fraction. Must not be zero.
  134.      * @param epsilon Maximum error allowed.
  135.      * The resulting fraction is within {@code epsilon} of {@code value},
  136.      * in absolute terms.
  137.      * @param maxDenominator Maximum denominator value allowed.
  138.      * @param maxIterations Maximum number of convergents.
  139.      * @throws IllegalArgumentException if the given {@code value} is NaN or infinite.
  140.      * @throws ArithmeticException if the continued fraction failed to converge.
  141.      */
  142.     private Fraction(final double value,
  143.                      final double epsilon,
  144.                      final int maxDenominator,
  145.                      final int maxIterations) {
  146.         if (!Double.isFinite(value)) {
  147.             throw new IllegalArgumentException(NOT_FINITE + value);
  148.         }

  149.         // Remove sign, this is restored at the end.
  150.         // (Assumes the value is not zero and thus signum(value) is not zero).
  151.         final double absValue = Math.abs(value);
  152.         double r0 = absValue;
  153.         long a0 = (long) Math.floor(r0);
  154.         if (a0 > OVERFLOW) {
  155.             throw new FractionException(FractionException.ERROR_CONVERSION_OVERFLOW, value, a0, 1);
  156.         }

  157.         // check for (almost) integer arguments, which should not go to iterations.
  158.         if (r0 - a0 <= epsilon) {
  159.             int num = (int) a0;
  160.             int den = 1;
  161.             // Restore the sign.
  162.             if (Math.signum(num) != Math.signum(value)) {
  163.                 if (num == Integer.MIN_VALUE) {
  164.                     den = -den;
  165.                 } else {
  166.                     num = -num;
  167.                 }
  168.             }
  169.             this.numerator = num;
  170.             this.denominator = den;
  171.             return;
  172.         }

  173.         // Support 2^31 as maximum denominator.
  174.         // This is negative as an integer so convert to long.
  175.         final long maxDen = Math.abs((long) maxDenominator);

  176.         long p0 = 1;
  177.         long q0 = 0;
  178.         long p1 = a0;
  179.         long q1 = 1;

  180.         long p2;
  181.         long q2;

  182.         int n = 0;
  183.         boolean stop = false;
  184.         do {
  185.             ++n;
  186.             final double r1 = 1.0 / (r0 - a0);
  187.             final long a1 = (long) Math.floor(r1);
  188.             p2 = (a1 * p1) + p0;
  189.             q2 = (a1 * q1) + q0;

  190.             if (Long.compareUnsigned(p2, OVERFLOW) > 0 ||
  191.                 Long.compareUnsigned(q2, OVERFLOW) > 0) {
  192.                 // In maxDenominator mode, fall-back to the previous valid fraction.
  193.                 if (epsilon == 0.0) {
  194.                     p2 = p1;
  195.                     q2 = q1;
  196.                     break;
  197.                 }
  198.                 throw new FractionException(FractionException.ERROR_CONVERSION_OVERFLOW, value, p2, q2);
  199.             }

  200.             final double convergent = (double) p2 / (double) q2;
  201.             if (n < maxIterations &&
  202.                 Math.abs(convergent - absValue) > epsilon &&
  203.                 q2 < maxDen) {
  204.                 p0 = p1;
  205.                 p1 = p2;
  206.                 q0 = q1;
  207.                 q1 = q2;
  208.                 a0 = a1;
  209.                 r0 = r1;
  210.             } else {
  211.                 stop = true;
  212.             }
  213.         } while (!stop);

  214.         if (n >= maxIterations) {
  215.             throw new FractionException(FractionException.ERROR_CONVERSION, value, maxIterations);
  216.         }

  217.         // Use p2 / q2 or p1 / q1 if q2 has grown too large in maxDenominator mode
  218.         // Note: Conversion of long 2^31 to an integer will create a negative. This could
  219.         // be either the numerator or denominator. This is handled by restoring the sign.
  220.         int num;
  221.         int den;
  222.         if (q2 <= maxDen) {
  223.             num = (int) p2;
  224.             den = (int) q2;
  225.         } else {
  226.             num = (int) p1;
  227.             den = (int) q1;
  228.         }

  229.         // Restore the sign.
  230.         if (Math.signum(num) * Math.signum(den) != Math.signum(value)) {
  231.             if (num == Integer.MIN_VALUE) {
  232.                 den = -den;
  233.             } else {
  234.                 num = -num;
  235.             }
  236.         }

  237.         this.numerator = num;
  238.         this.denominator = den;
  239.     }

  240.     /**
  241.      * Create a fraction given the double value.
  242.      *
  243.      * @param value Value to convert to a fraction.
  244.      * @throws IllegalArgumentException if the given {@code value} is NaN or infinite.
  245.      * @throws ArithmeticException if the continued fraction failed to converge.
  246.      * @return a new instance.
  247.      */
  248.     public static Fraction from(final double value) {
  249.         return from(value, DEFAULT_EPSILON, DEFAULT_MAX_ITERATIONS);
  250.     }

  251.     /**
  252.      * Create a fraction given the double value and maximum error allowed.
  253.      *
  254.      * <p>
  255.      * References:
  256.      * <ul>
  257.      * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
  258.      * Continued Fraction</a> equations (11) and (22)-(26)</li>
  259.      * </ul>
  260.      *
  261.      * @param value Value to convert to a fraction.
  262.      * @param epsilon Maximum error allowed. The resulting fraction is within
  263.      * {@code epsilon} of {@code value}, in absolute terms.
  264.      * @param maxIterations Maximum number of convergents.
  265.      * @throws IllegalArgumentException if the given {@code value} is NaN or infinite;
  266.      * {@code epsilon} is not positive; or {@code maxIterations < 1}.
  267.      * @throws ArithmeticException if the continued fraction failed to converge.
  268.      * @return a new instance.
  269.      */
  270.     public static Fraction from(final double value,
  271.                                 final double epsilon,
  272.                                 final int maxIterations) {
  273.         if (value == 0) {
  274.             return ZERO;
  275.         }
  276.         if (maxIterations < 1) {
  277.             throw new IllegalArgumentException("Max iterations must be strictly positive: " + maxIterations);
  278.         }
  279.         if (epsilon >= 0) {
  280.             return new Fraction(value, epsilon, Integer.MIN_VALUE, maxIterations);
  281.         }
  282.         throw new IllegalArgumentException("Epsilon must be positive: " + maxIterations);
  283.     }

  284.     /**
  285.      * Create a fraction given the double value and maximum denominator.
  286.      *
  287.      * <p>
  288.      * References:
  289.      * <ul>
  290.      * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
  291.      * Continued Fraction</a> equations (11) and (22)-(26)</li>
  292.      * </ul>
  293.      *
  294.      * <p>Note: The magnitude of the {@code maxDenominator} is used allowing use of
  295.      * {@link Integer#MIN_VALUE} for a supported maximum denominator of 2<sup>31</sup>.
  296.      *
  297.      * @param value Value to convert to a fraction.
  298.      * @param maxDenominator Maximum allowed value for denominator.
  299.      * @throws IllegalArgumentException if the given {@code value} is NaN or infinite
  300.      * or {@code maxDenominator} is zero.
  301.      * @throws ArithmeticException if the continued fraction failed to converge.
  302.      * @return a new instance.
  303.      */
  304.     public static Fraction from(final double value,
  305.                                 final int maxDenominator) {
  306.         if (value == 0) {
  307.             return ZERO;
  308.         }
  309.         if (maxDenominator == 0) {
  310.             // Re-use the zero denominator message
  311.             throw new IllegalArgumentException(FractionException.ERROR_ZERO_DENOMINATOR);
  312.         }
  313.         return new Fraction(value, 0, maxDenominator, DEFAULT_MAX_ITERATIONS);
  314.     }

  315.     /**
  316.      * Create a fraction given the numerator. The denominator is {@code 1}.
  317.      *
  318.      * @param num Numerator.
  319.      * @return a new instance.
  320.      */
  321.     public static Fraction of(final int num) {
  322.         if (num == 0) {
  323.             return ZERO;
  324.         }
  325.         return new Fraction(num);
  326.     }

  327.     /**
  328.      * Create a fraction given the numerator and denominator.
  329.      * The fraction is reduced to lowest terms.
  330.      *
  331.      * @param num Numerator.
  332.      * @param den Denominator.
  333.      * @throws ArithmeticException if the denominator is {@code zero}.
  334.      * @return a new instance.
  335.      */
  336.     public static Fraction of(final int num, final int den) {
  337.         if (num == 0) {
  338.             return ZERO;
  339.         }
  340.         return new Fraction(num, den);
  341.     }

  342.     /**
  343.      * Returns a {@code Fraction} instance representing the specified string {@code s}.
  344.      *
  345.      * <p>If {@code s} is {@code null}, then a {@code NullPointerException} is thrown.
  346.      *
  347.      * <p>The string must be in a format compatible with that produced by
  348.      * {@link #toString() Fraction.toString()}.
  349.      * The format expects an integer optionally followed by a {@code '/'} character and
  350.      * and second integer. Leading and trailing spaces are allowed around each numeric part.
  351.      * Each numeric part is parsed using {@link Integer#parseInt(String)}. The parts
  352.      * are interpreted as the numerator and optional denominator of the fraction. If absent
  353.      * the denominator is assumed to be "1".
  354.      *
  355.      * <p>Examples of valid strings and the equivalent {@code Fraction} are shown below:
  356.      *
  357.      * <pre>
  358.      * "0"                 = Fraction.of(0)
  359.      * "42"                = Fraction.of(42)
  360.      * "0 / 1"             = Fraction.of(0, 1)
  361.      * "1 / 3"             = Fraction.of(1, 3)
  362.      * "-4 / 13"           = Fraction.of(-4, 13)</pre>
  363.      *
  364.      * <p>Note: The fraction is returned in reduced form and the numerator and denominator
  365.      * may not match the values in the input string. For this reason the result of
  366.      * {@code Fraction.parse(s).toString().equals(s)} may not be {@code true}.
  367.      *
  368.      * @param s String representation.
  369.      * @return an instance.
  370.      * @throws NullPointerException if the string is null.
  371.      * @throws NumberFormatException if the string does not contain a parsable fraction.
  372.      * @see Integer#parseInt(String)
  373.      * @see #toString()
  374.      */
  375.     public static Fraction parse(String s) {
  376.         final String stripped = s.replace(",", "");
  377.         final int slashLoc = stripped.indexOf('/');
  378.         // if no slash, parse as single number
  379.         if (slashLoc == -1) {
  380.             return of(Integer.parseInt(stripped.trim()));
  381.         }
  382.         final int num = Integer.parseInt(stripped.substring(0, slashLoc).trim());
  383.         final int denom = Integer.parseInt(stripped.substring(slashLoc + 1).trim());
  384.         return of(num, denom);
  385.     }

  386.     @Override
  387.     public Fraction zero() {
  388.         return ZERO;
  389.     }

  390.     /** {@inheritDoc} */
  391.     @Override
  392.     public boolean isZero() {
  393.         return numerator == 0;
  394.     }

  395.     @Override
  396.     public Fraction one() {
  397.         return ONE;
  398.     }

  399.     /** {@inheritDoc} */
  400.     @Override
  401.     public boolean isOne() {
  402.         return numerator == denominator;
  403.     }

  404.     /**
  405.      * Access the numerator as an {@code int}.
  406.      *
  407.      * @return the numerator as an {@code int}.
  408.      */
  409.     public int getNumerator() {
  410.         return numerator;
  411.     }

  412.     /**
  413.      * Access the denominator as an {@code int}.
  414.      *
  415.      * @return the denominator as an {@code int}.
  416.      */
  417.     public int getDenominator() {
  418.         return denominator;
  419.     }

  420.     /**
  421.      * Retrieves the sign of this fraction.
  422.      *
  423.      * @return -1 if the value is strictly negative, 1 if it is strictly
  424.      * positive, 0 if it is 0.
  425.      */
  426.     public int signum() {
  427.         return Integer.signum(numerator) * Integer.signum(denominator);
  428.     }

  429.     /**
  430.      * Returns the absolute value of this fraction.
  431.      *
  432.      * @return the absolute value.
  433.      */
  434.     public Fraction abs() {
  435.         return signum() >= 0 ?
  436.             this :
  437.             negate();
  438.     }

  439.     @Override
  440.     public Fraction negate() {
  441.         return numerator == Integer.MIN_VALUE ?
  442.             new Fraction(numerator, -denominator) :
  443.             new Fraction(-numerator, denominator);
  444.     }

  445.     /**
  446.      * {@inheritDoc}
  447.      *
  448.      * <p>Raises an exception if the fraction is equal to zero.
  449.      *
  450.      * @throws ArithmeticException if the current numerator is {@code zero}
  451.      */
  452.     @Override
  453.     public Fraction reciprocal() {
  454.         return new Fraction(denominator, numerator);
  455.     }

  456.     /**
  457.      * Returns the {@code double} value closest to this fraction.
  458.      * This calculates the fraction as numerator divided by denominator.
  459.      *
  460.      * @return the fraction as a {@code double}.
  461.      */
  462.     @Override
  463.     public double doubleValue() {
  464.         return (double) numerator / (double) denominator;
  465.     }

  466.     /**
  467.      * Returns the {@code float} value closest to this fraction.
  468.      * This calculates the fraction as numerator divided by denominator.
  469.      *
  470.      * @return the fraction as a {@code float}.
  471.      */
  472.     @Override
  473.     public float floatValue() {
  474.         return (float) doubleValue();
  475.     }

  476.     /**
  477.      * Returns the whole number part of the fraction.
  478.      *
  479.      * @return the largest {@code int} value that is not larger than this fraction.
  480.      */
  481.     @Override
  482.     public int intValue() {
  483.         // Note: numerator / denominator fails for Integer.MIN_VALUE / -1.
  484.         // Casting the double value handles this case.
  485.         return (int) doubleValue();
  486.     }

  487.     /**
  488.      * Returns the whole number part of the fraction.
  489.      *
  490.      * @return the largest {@code long} value that is not larger than this fraction.
  491.      */
  492.     @Override
  493.     public long longValue() {
  494.         return (long) numerator / denominator;
  495.     }

  496.     /**
  497.      * Adds the specified {@code value} to this fraction, returning
  498.      * the result in reduced form.
  499.      *
  500.      * @param value Value to add.
  501.      * @return {@code this + value}.
  502.      * @throws ArithmeticException if the resulting numerator
  503.      * cannot be represented in an {@code int}.
  504.      */
  505.     public Fraction add(final int value) {
  506.         if (value == 0) {
  507.             return this;
  508.         }
  509.         if (isZero()) {
  510.             return new Fraction(value);
  511.         }
  512.         // Convert to numerator with same effective denominator
  513.         final long num = (long) value * denominator;
  514.         return of(Math.toIntExact(numerator + num), denominator);
  515.     }

  516.     /**
  517.      * Adds the specified {@code value} to this fraction, returning
  518.      * the result in reduced form.
  519.      *
  520.      * @param value Value to add.
  521.      * @return {@code this + value}.
  522.      * @throws ArithmeticException if the resulting numerator or denominator
  523.      * cannot be represented in an {@code int}.
  524.      */
  525.     @Override
  526.     public Fraction add(Fraction value) {
  527.         return addSub(value, true /* add */);
  528.     }

  529.     /**
  530.      * Subtracts the specified {@code value} from this fraction, returning
  531.      * the result in reduced form.
  532.      *
  533.      * @param value Value to subtract.
  534.      * @return {@code this - value}.
  535.      * @throws ArithmeticException if the resulting numerator
  536.      * cannot be represented in an {@code int}.
  537.      */
  538.     public Fraction subtract(final int value) {
  539.         if (value == 0) {
  540.             return this;
  541.         }
  542.         if (isZero()) {
  543.             // Special case for min value
  544.             return value == Integer.MIN_VALUE ?
  545.                 new Fraction(Integer.MIN_VALUE, -1) :
  546.                 new Fraction(-value);
  547.         }
  548.         // Convert to numerator with same effective denominator
  549.         final long num = (long) value * denominator;
  550.         return of(Math.toIntExact(numerator - num), denominator);
  551.     }

  552.     /**
  553.      * Subtracts the specified {@code value} from this fraction, returning
  554.      * the result in reduced form.
  555.      *
  556.      * @param value Value to subtract.
  557.      * @return {@code this - value}.
  558.      * @throws ArithmeticException if the resulting numerator or denominator
  559.      * cannot be represented in an {@code int}.
  560.      */
  561.     @Override
  562.     public Fraction subtract(Fraction value) {
  563.         return addSub(value, false /* subtract */);
  564.     }

  565.     /**
  566.      * Implements add and subtract using algorithm described in Knuth 4.5.1.
  567.      *
  568.      * @param value Fraction to add or subtract.
  569.      * @param isAdd Whether the operation is "add" or "subtract".
  570.      * @return a new instance.
  571.      * @throws ArithmeticException if the resulting numerator or denominator
  572.      * cannot be represented in an {@code int}.
  573.      */
  574.     private Fraction addSub(Fraction value, boolean isAdd) {
  575.         if (value.isZero()) {
  576.             return this;
  577.         }
  578.         // Zero is identity for addition.
  579.         if (isZero()) {
  580.             return isAdd ? value : value.negate();
  581.         }

  582.         /*
  583.          * Let the two fractions be u/u' and v/v', and d1 = gcd(u', v').
  584.          * First, compute t, defined as:
  585.          *
  586.          * t = u(v'/d1) +/- v(u'/d1)
  587.          */
  588.         final int d1 = ArithmeticUtils.gcd(denominator, value.denominator);
  589.         final long uvp = (long) numerator * (long) (value.denominator / d1);
  590.         final long upv = (long) value.numerator * (long) (denominator / d1);

  591.         /*
  592.          * The largest possible absolute value of a product of two ints is 2^62,
  593.          * which can only happen as a result of -2^31 * -2^31 = 2^62, so a
  594.          * product of -2^62 is not possible. It follows that (uvp - upv) cannot
  595.          * overflow, and (uvp + upv) could only overflow if uvp = upv = 2^62.
  596.          * But for this to happen, the terms u, v, v'/d1 and u'/d1 would all
  597.          * have to be -2^31, which is not possible because v'/d1 and u'/d1
  598.          * are necessarily coprime.
  599.          */
  600.         final long t = isAdd ? uvp + upv : uvp - upv;

  601.         /*
  602.          * Because u is coprime to u' and v is coprime to v', t is necessarily
  603.          * coprime to both v'/d1 and u'/d1. However, it might have a common
  604.          * factor with d1.
  605.          */
  606.         final long d2 = ArithmeticUtils.gcd(t, d1);
  607.         // result is (t/d2) / (u'/d1)(v'/d2)
  608.         return of(Math.toIntExact(t / d2),
  609.                   Math.multiplyExact(denominator / d1,
  610.                                      value.denominator / (int) d2));
  611.     }

  612.     /**
  613.      * Multiply this fraction by the passed {@code value}, returning
  614.      * the result in reduced form.
  615.      *
  616.      * @param value Value to multiply by.
  617.      * @return {@code this * value}.
  618.      * @throws ArithmeticException if the resulting numerator
  619.      * cannot be represented in an {@code int}.
  620.      */
  621.     @Override
  622.     public Fraction multiply(final int value) {
  623.         if (value == 0 || isZero()) {
  624.             return ZERO;
  625.         }

  626.         // knuth 4.5.1
  627.         // Make sure we don't overflow unless the result *must* overflow.
  628.         // (see multiply(Fraction) using value / 1 as the argument).
  629.         final int d2 = ArithmeticUtils.gcd(value, denominator);
  630.         return new Fraction(Math.multiplyExact(numerator, value / d2),
  631.                             denominator / d2);
  632.     }

  633.     /**
  634.      * Multiply this fraction by the passed {@code value}, returning
  635.      * the result in reduced form.
  636.      *
  637.      * @param value Value to multiply by.
  638.      * @return {@code this * value}.
  639.      * @throws ArithmeticException if the resulting numerator or denominator
  640.      * cannot be represented in an {@code int}.
  641.      */
  642.     @Override
  643.     public Fraction multiply(Fraction value) {
  644.         if (value.isZero() || isZero()) {
  645.             return ZERO;
  646.         }
  647.         return multiply(value.numerator, value.denominator);
  648.     }

  649.     /**
  650.      * Multiply this fraction by the passed fraction decomposed into a numerator and
  651.      * denominator, returning the result in reduced form.
  652.      *
  653.      * <p>This is a utility method to be used by multiply and divide. The decomposed
  654.      * fraction arguments and this fraction are not checked for zero.
  655.      *
  656.      * @param num Fraction numerator.
  657.      * @param den Fraction denominator.
  658.      * @return {@code this * num / den}.
  659.      * @throws ArithmeticException if the resulting numerator or denominator cannot
  660.      * be represented in an {@code int}.
  661.      */
  662.     private Fraction multiply(int num, int den) {
  663.         // knuth 4.5.1
  664.         // Make sure we don't overflow unless the result *must* overflow.
  665.         final int d1 = ArithmeticUtils.gcd(numerator, den);
  666.         final int d2 = ArithmeticUtils.gcd(num, denominator);
  667.         return new Fraction(Math.multiplyExact(numerator / d1, num / d2),
  668.                             Math.multiplyExact(denominator / d2, den / d1));
  669.     }

  670.     /**
  671.      * Divide this fraction by the passed {@code value}, returning
  672.      * the result in reduced form.
  673.      *
  674.      * @param value Value to divide by
  675.      * @return {@code this / value}.
  676.      * @throws ArithmeticException if the value to divide by is zero
  677.      * or if the resulting numerator or denominator cannot be represented
  678.      * by an {@code int}.
  679.      */
  680.     public Fraction divide(final int value) {
  681.         if (value == 0) {
  682.             throw new FractionException(FractionException.ERROR_DIVIDE_BY_ZERO);
  683.         }
  684.         if (isZero()) {
  685.             return ZERO;
  686.         }
  687.         // Multiply by reciprocal

  688.         // knuth 4.5.1
  689.         // Make sure we don't overflow unless the result *must* overflow.
  690.         // (see multiply(Fraction) using 1 / value as the argument).
  691.         final int d1 = ArithmeticUtils.gcd(numerator, value);
  692.         return new Fraction(numerator / d1,
  693.                             Math.multiplyExact(denominator, value / d1));
  694.     }

  695.     /**
  696.      * Divide this fraction by the passed {@code value}, returning
  697.      * the result in reduced form.
  698.      *
  699.      * @param value Value to divide by
  700.      * @return {@code this / value}.
  701.      * @throws ArithmeticException if the value to divide by is zero
  702.      * or if the resulting numerator or denominator cannot be represented
  703.      * by an {@code int}.
  704.      */
  705.     @Override
  706.     public Fraction divide(Fraction value) {
  707.         if (value.isZero()) {
  708.             throw new FractionException(FractionException.ERROR_DIVIDE_BY_ZERO);
  709.         }
  710.         if (isZero()) {
  711.             return ZERO;
  712.         }
  713.         // Multiply by reciprocal
  714.         return multiply(value.denominator, value.numerator);
  715.     }

  716.     /**
  717.      * Returns a {@code Fraction} whose value is
  718.      * <code>this<sup>exponent</sup></code>, returning the result in reduced form.
  719.      *
  720.      * @param exponent exponent to which this {@code Fraction} is to be raised.
  721.      * @return <code>this<sup>exponent</sup></code>.
  722.      * @throws ArithmeticException if the intermediate result would overflow.
  723.      */
  724.     @Override
  725.     public Fraction pow(final int exponent) {
  726.         if (exponent == 1) {
  727.             return this;
  728.         }
  729.         if (exponent == 0) {
  730.             return ONE;
  731.         }
  732.         if (isZero()) {
  733.             if (exponent < 0) {
  734.                 throw new FractionException(FractionException.ERROR_ZERO_DENOMINATOR);
  735.             }
  736.             return ZERO;
  737.         }
  738.         if (exponent > 0) {
  739.             return new Fraction(ArithmeticUtils.pow(numerator, exponent),
  740.                                 ArithmeticUtils.pow(denominator, exponent));
  741.         }
  742.         if (exponent == -1) {
  743.             return this.reciprocal();
  744.         }
  745.         if (exponent == Integer.MIN_VALUE) {
  746.             // MIN_VALUE can't be negated
  747.             return new Fraction(ArithmeticUtils.pow(denominator, Integer.MAX_VALUE) * denominator,
  748.                                 ArithmeticUtils.pow(numerator, Integer.MAX_VALUE) * numerator);
  749.         }
  750.         return new Fraction(ArithmeticUtils.pow(denominator, -exponent),
  751.                             ArithmeticUtils.pow(numerator, -exponent));
  752.     }

  753.     /**
  754.      * Returns the {@code String} representing this fraction.
  755.      * Uses:
  756.      * <ul>
  757.      *  <li>{@code "0"} if {@code numerator} is zero.
  758.      *  <li>{@code "numerator"} if {@code denominator} is one.
  759.      *  <li>{@code "numerator / denominator"} for all other cases.
  760.      * </ul>
  761.      *
  762.      * @return a string representation of the fraction.
  763.      */
  764.     @Override
  765.     public String toString() {
  766.         final String str;
  767.         if (isZero()) {
  768.             str = "0";
  769.         } else if (denominator == 1) {
  770.             str = Integer.toString(numerator);
  771.         } else {
  772.             str = numerator + " / " + denominator;
  773.         }
  774.         return str;
  775.     }

  776.     /**
  777.      * Compares this object with the specified object for order using the signed magnitude.
  778.      *
  779.      * @param other {@inheritDoc}
  780.      * @return {@inheritDoc}
  781.      */
  782.     @Override
  783.     public int compareTo(Fraction other) {
  784.         // Compute the sign of each part
  785.         final int lns = Integer.signum(numerator);
  786.         final int lds = Integer.signum(denominator);
  787.         final int rns = Integer.signum(other.numerator);
  788.         final int rds = Integer.signum(other.denominator);

  789.         final int lhsSigNum = lns * lds;
  790.         final int rhsSigNum = rns * rds;

  791.         if (lhsSigNum != rhsSigNum) {
  792.             return (lhsSigNum > rhsSigNum) ? 1 : -1;
  793.         }
  794.         // Same sign.
  795.         // Avoid a multiply if both fractions are zero
  796.         if (lhsSigNum == 0) {
  797.             return 0;
  798.         }
  799.         // Compare absolute magnitude.
  800.         // Multiplication by the signum is equal to the absolute.
  801.         final long nOd = ((long) numerator) * lns * other.denominator * rds;
  802.         final long dOn = ((long) denominator) * lds * other.numerator * rns;
  803.         return Long.compare(nOd, dOn);
  804.     }

  805.     /**
  806.      * Test for equality with another object. If the other object is a {@code Fraction} then a
  807.      * comparison is made of the sign and magnitude; otherwise {@code false} is returned.
  808.      *
  809.      * @param other {@inheritDoc}
  810.      * @return {@inheritDoc}
  811.      */
  812.     @Override
  813.     public boolean equals(Object other) {
  814.         if (this == other) {
  815.             return true;
  816.         }

  817.         if (other instanceof Fraction) {
  818.             // Since fractions are always in lowest terms, numerators and
  819.             // denominators can be compared directly for equality.
  820.             final Fraction rhs = (Fraction) other;
  821.             if (signum() == rhs.signum()) {
  822.                 return Math.abs(numerator) == Math.abs(rhs.numerator) &&
  823.                        Math.abs(denominator) == Math.abs(rhs.denominator);
  824.             }
  825.         }

  826.         return false;
  827.     }

  828.     @Override
  829.     public int hashCode() {
  830.         // Incorporate the sign and absolute values of the numerator and denominator.
  831.         // Equivalent to:
  832.         // int hash = 1;
  833.         // hash = 31 * hash + Math.abs(numerator);
  834.         // hash = 31 * hash + Math.abs(denominator);
  835.         // hash = hash * signum()
  836.         // Note: x * Integer.signum(x) == Math.abs(x).
  837.         final int numS = Integer.signum(numerator);
  838.         final int denS = Integer.signum(denominator);
  839.         return (31 * (31 + numerator * numS) + denominator * denS) * numS * denS;
  840.     }
  841. }