BigFraction.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.  *      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.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.fraction;

  22. import java.io.Serializable;
  23. import java.math.BigDecimal;
  24. import java.math.BigInteger;
  25. import java.math.RoundingMode;
  26. import java.util.function.Function;
  27. import java.util.stream.Stream;

  28. import org.hipparchus.FieldElement;
  29. import org.hipparchus.exception.LocalizedCoreFormats;
  30. import org.hipparchus.exception.MathIllegalArgumentException;
  31. import org.hipparchus.exception.MathIllegalStateException;
  32. import org.hipparchus.exception.MathRuntimeException;
  33. import org.hipparchus.exception.NullArgumentException;
  34. import org.hipparchus.fraction.ConvergentsIterator.ConvergenceStep;
  35. import org.hipparchus.util.ArithmeticUtils;
  36. import org.hipparchus.util.FastMath;
  37. import org.hipparchus.util.MathUtils;
  38. import org.hipparchus.util.Pair;
  39. import org.hipparchus.util.Precision;

  40. /**
  41.  * Representation of a rational number without any overflow. This class is
  42.  * immutable.
  43.  *
  44.  */
  45. public class BigFraction
  46.     extends Number
  47.     implements FieldElement<BigFraction>, Comparable<BigFraction>, Serializable {

  48.     /** A fraction representing "2 / 1". */
  49.     public static final BigFraction TWO = new BigFraction(2);

  50.     /** A fraction representing "1". */
  51.     public static final BigFraction ONE = new BigFraction(1);

  52.     /** A fraction representing "0". */
  53.     public static final BigFraction ZERO = new BigFraction(0);

  54.     /** A fraction representing "-1 / 1". */
  55.     public static final BigFraction MINUS_ONE = new BigFraction(-1);

  56.     /** A fraction representing "4/5". */
  57.     public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5);

  58.     /** A fraction representing "1/5". */
  59.     public static final BigFraction ONE_FIFTH = new BigFraction(1, 5);

  60.     /** A fraction representing "1/2". */
  61.     public static final BigFraction ONE_HALF = new BigFraction(1, 2);

  62.     /** A fraction representing "1/4". */
  63.     public static final BigFraction ONE_QUARTER = new BigFraction(1, 4);

  64.     /** A fraction representing "1/3". */
  65.     public static final BigFraction ONE_THIRD = new BigFraction(1, 3);

  66.     /** A fraction representing "3/5". */
  67.     public static final BigFraction THREE_FIFTHS = new BigFraction(3, 5);

  68.     /** A fraction representing "3/4". */
  69.     public static final BigFraction THREE_QUARTERS = new BigFraction(3, 4);

  70.     /** A fraction representing "2/5". */
  71.     public static final BigFraction TWO_FIFTHS = new BigFraction(2, 5);

  72.     /** A fraction representing "2/4". */
  73.     public static final BigFraction TWO_QUARTERS = new BigFraction(2, 4);

  74.     /** A fraction representing "2/3". */
  75.     public static final BigFraction TWO_THIRDS = new BigFraction(2, 3);

  76.     /** Serializable version identifier. */
  77.     private static final long serialVersionUID = -5630213147331578515L;

  78.     /** <code>BigInteger</code> representation of 100. */
  79.     private static final BigInteger ONE_HUNDRED = BigInteger.valueOf(100);

  80.     /** Convert a convergence step to the corresponding double fraction. */
  81.     private static final Function<ConvergenceStep, BigFraction> STEP_TO_FRACTION = //
  82.             s -> new BigFraction(s.getNumerator(), s.getDenominator());

  83.     /** The numerator. */
  84.     private final BigInteger numerator;

  85.     /** The denominator. */
  86.     private final BigInteger denominator;

  87.     /**
  88.      * <p>
  89.      * Create a {@link BigFraction} equivalent to the passed {@code BigInteger}, ie
  90.      * "num / 1".
  91.      * </p>
  92.      *
  93.      * @param num
  94.      *            the numerator.
  95.      */
  96.     public BigFraction(final BigInteger num) {
  97.         this(num, BigInteger.ONE);
  98.     }

  99.     /**
  100.      * Create a {@link BigFraction} given the numerator and denominator as
  101.      * {@code BigInteger}. The {@link BigFraction} is reduced to lowest terms.
  102.      *
  103.      * @param num the numerator, must not be {@code null}.
  104.      * @param den the denominator, must not be {@code null}.
  105.      * @throws MathIllegalArgumentException if the denominator is zero.
  106.      * @throws NullArgumentException if either of the arguments is null
  107.      */
  108.     public BigFraction(BigInteger num, BigInteger den) {
  109.         MathUtils.checkNotNull(num, LocalizedCoreFormats.NUMERATOR);
  110.         MathUtils.checkNotNull(den, LocalizedCoreFormats.DENOMINATOR);
  111.         if (den.signum() == 0) {
  112.             throw new MathIllegalArgumentException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  113.         }
  114.         if (num.signum() == 0) {
  115.             numerator   = BigInteger.ZERO;
  116.             denominator = BigInteger.ONE;
  117.         } else {

  118.             // reduce numerator and denominator by greatest common denominator
  119.             final BigInteger gcd = num.gcd(den);
  120.             if (BigInteger.ONE.compareTo(gcd) < 0) {
  121.                 num = num.divide(gcd);
  122.                 den = den.divide(gcd);
  123.             }

  124.             // move sign to numerator
  125.             if (den.signum() == -1) {
  126.                 num = num.negate();
  127.                 den = den.negate();
  128.             }

  129.             // store the values in the final fields
  130.             numerator   = num;
  131.             denominator = den;

  132.         }
  133.     }

  134.     /**
  135.      * Create a fraction given the double value.
  136.      * <p>
  137.      * This constructor behaves <em>differently</em> from
  138.      * {@link #BigFraction(double, double, int)}. It converts the double value
  139.      * exactly, considering its internal bits representation. This works for all
  140.      * values except NaN and infinities and does not requires any loop or
  141.      * convergence threshold.
  142.      * </p>
  143.      * <p>
  144.      * Since this conversion is exact and since double numbers are sometimes
  145.      * approximated, the fraction created may seem strange in some cases. For example,
  146.      * calling <code>new BigFraction(1.0 / 3.0)</code> does <em>not</em> create
  147.      * the fraction 1/3, but the fraction 6004799503160661 / 18014398509481984
  148.      * because the double number passed to the constructor is not exactly 1/3
  149.      * (this number cannot be stored exactly in IEEE754).
  150.      * </p>
  151.      * @see #BigFraction(double, double, int)
  152.      * @param value the double value to convert to a fraction.
  153.      * @exception MathIllegalArgumentException if value is NaN or infinite
  154.      */
  155.     public BigFraction(final double value) throws MathIllegalArgumentException {
  156.         if (Double.isNaN(value)) {
  157.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NAN_VALUE_CONVERSION);
  158.         }
  159.         if (Double.isInfinite(value)) {
  160.             throw new MathIllegalArgumentException(LocalizedCoreFormats.INFINITE_VALUE_CONVERSION);
  161.         }

  162.         // compute m and k such that value = m * 2^k
  163.         final long bits     = Double.doubleToLongBits(value);
  164.         final long sign     = bits & 0x8000000000000000L;
  165.         final long exponent = bits & 0x7ff0000000000000L;
  166.         long m              = bits & 0x000fffffffffffffL;
  167.         if (exponent != 0) {
  168.             // this was a normalized number, add the implicit most significant bit
  169.             m |= 0x0010000000000000L;
  170.         }
  171.         if (sign != 0) {
  172.             m = -m;
  173.         }
  174.         int k = ((int) (exponent >> 52)) - 1075;
  175.         while (((m & 0x001ffffffffffffeL) != 0) && ((m & 0x1) == 0)) {
  176.             m >>= 1;
  177.             ++k;
  178.         }

  179.         if (k < 0) {
  180.             numerator   = BigInteger.valueOf(m);
  181.             denominator = BigInteger.ZERO.flipBit(-k);
  182.         } else {
  183.             numerator   = BigInteger.valueOf(m).multiply(BigInteger.ZERO.flipBit(k));
  184.             denominator = BigInteger.ONE;
  185.         }

  186.     }

  187.     /**
  188.      * Create a fraction given the double value and maximum error allowed.
  189.      * <p>* References:</p>
  190.      * <ul>
  191.      * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
  192.      * Continued Fraction</a> equations (11) and (22)-(26)</li>
  193.      * </ul>
  194.      *
  195.      * @param value
  196.      *            the double value to convert to a fraction.
  197.      * @param epsilon
  198.      *            maximum error allowed. The resulting fraction is within
  199.      *            <code>epsilon</code> of <code>value</code>, in absolute terms.
  200.      * @param maxIterations
  201.      *            maximum number of convergents.
  202.      * @throws MathIllegalStateException
  203.      *             if the continued fraction failed to converge.
  204.      * @see #BigFraction(double)
  205.      */
  206.     public BigFraction(final double value, final double epsilon,
  207.                        final int maxIterations)
  208.         throws MathIllegalStateException {
  209.         ConvergenceStep converged = ConvergentsIterator.convergent(value, maxIterations, s -> {
  210.             final double quotient = s.getFractionValue();
  211.             return Precision.equals(quotient, value, 1) || FastMath.abs(quotient - value) < epsilon;
  212.         }).getKey();
  213.         if (FastMath.abs(converged.getFractionValue() - value) < epsilon) {
  214.             this.numerator = BigInteger.valueOf(converged.getNumerator());
  215.             this.denominator = BigInteger.valueOf(converged.getDenominator());
  216.         } else {
  217.             throw new MathIllegalStateException(LocalizedCoreFormats.FAILED_FRACTION_CONVERSION,
  218.                                                 value, maxIterations);
  219.         }
  220.     }

  221.     /**
  222.      * Create a fraction given the double value and maximum denominator.
  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 maxDenominator
  232.      *            The maximum allowed value for denominator.
  233.      * @throws MathIllegalStateException
  234.      *             if the continued fraction failed to converge.
  235.      */
  236.     public BigFraction(final double value, final long maxDenominator)
  237.         throws MathIllegalStateException {
  238.         final int maxIterations = 100;
  239.         ConvergenceStep[] lastValid = new ConvergenceStep[1];
  240.         ConvergentsIterator.convergent(value, maxIterations, s -> {
  241.             if (s.getDenominator() < maxDenominator) {
  242.                 lastValid[0] = s;
  243.             }
  244.             return Precision.equals(s.getFractionValue(), value, 1);
  245.         });
  246.         if (lastValid[0] != null) {
  247.             this.numerator   = BigInteger.valueOf(lastValid[0].getNumerator());
  248.             this.denominator = BigInteger.valueOf(lastValid[0].getDenominator());
  249.         } else {
  250.             throw new MathIllegalStateException(LocalizedCoreFormats.FAILED_FRACTION_CONVERSION,
  251.                                                 value, maxIterations);
  252.         }
  253.     }

  254.     /**
  255.      * <p>
  256.      * Create a {@link BigFraction} equivalent to the passed {@code int}, ie
  257.      * "num / 1".
  258.      * </p>
  259.      *
  260.      * @param num
  261.      *            the numerator.
  262.      */
  263.     public BigFraction(final int num) {
  264.         this(BigInteger.valueOf(num), BigInteger.ONE);
  265.     }

  266.     /**
  267.      * <p>
  268.      * Create a {@link BigFraction} given the numerator and denominator as simple
  269.      * {@code int}. The {@link BigFraction} is reduced to lowest terms.
  270.      * </p>
  271.      *
  272.      * @param num
  273.      *            the numerator.
  274.      * @param den
  275.      *            the denominator.
  276.      */
  277.     public BigFraction(final int num, final int den) {
  278.         this(BigInteger.valueOf(num), BigInteger.valueOf(den));
  279.     }

  280.     /**
  281.      * <p>
  282.      * Create a {@link BigFraction} equivalent to the passed long, ie "num / 1".
  283.      * </p>
  284.      *
  285.      * @param num
  286.      *            the numerator.
  287.      */
  288.     public BigFraction(final long num) {
  289.         this(BigInteger.valueOf(num), BigInteger.ONE);
  290.     }

  291.     /**
  292.      * <p>
  293.      * Create a {@link BigFraction} given the numerator and denominator as simple
  294.      * {@code long}. The {@link BigFraction} is reduced to lowest terms.
  295.      * </p>
  296.      *
  297.      * @param num
  298.      *            the numerator.
  299.      * @param den
  300.      *            the denominator.
  301.      */
  302.     public BigFraction(final long num, final long den) {
  303.         this(BigInteger.valueOf(num), BigInteger.valueOf(den));
  304.     }

  305.     /**
  306.      * A test to determine if a series of fractions has converged.
  307.      */
  308.     @FunctionalInterface
  309.     public interface ConvergenceTest {
  310.         /**
  311.          * Evaluates if the fraction formed by {@code numerator/denominator} satisfies
  312.          * this convergence test.
  313.          *
  314.          * @param numerator   the numerator
  315.          * @param denominator the denominator
  316.          * @return if this convergence test is satisfied
  317.          */
  318.         boolean test(long numerator, long denominator); // NOPMD - this is not a Junit test, PMD false positive here
  319.     }

  320.     /** Generate a {@link Stream stream} of convergents from a real number.
  321.      * @param value value to approximate
  322.      * @param maxConvergents maximum number of convergents.
  323.      * @return stream of {@link BigFraction} convergents approximating  {@code value}
  324.      * @since 2.1
  325.      */
  326.     public static Stream<BigFraction> convergents(final double value, final int maxConvergents) {
  327.         return ConvergentsIterator.convergents(value, maxConvergents).map(STEP_TO_FRACTION);
  328.     }

  329.     /**
  330.      * Returns the last element of the series of convergent-steps to approximate the
  331.      * given value.
  332.      * <p>
  333.      * The series terminates either at the first step that satisfies the given
  334.      * {@code convergenceTest} or after at most {@code maxConvergents} elements. The
  335.      * returned Pair consists of that terminal {@link BigFraction} and a
  336.      * {@link Boolean} that indicates if it satisfies the given convergence tests.
  337.      * If the returned pair's value is {@code false} the element at position
  338.      * {@code maxConvergents} was examined but failed to satisfy the
  339.      * {@code convergenceTest}. A caller can then decide to accept the result
  340.      * nevertheless or to discard it. This method is usually faster than
  341.      * {@link #convergents(double, int)} if only the terminal element is of
  342.      * interest.
  343.      *
  344.      * @param value           value to approximate
  345.      * @param maxConvergents  maximum number of convergents to examine
  346.      * @param convergenceTest the test if the series has converged at a step
  347.      * @return the pair of last element of the series of convergents and a boolean
  348.      *         indicating if that element satisfies the specified convergent test
  349.      */
  350.     public static Pair<BigFraction, Boolean> convergent(double value, int maxConvergents,
  351.             ConvergenceTest convergenceTest) {
  352.         Pair<ConvergenceStep, Boolean> converged = ConvergentsIterator.convergent(value, maxConvergents,
  353.                 s -> convergenceTest.test(s.getNumerator(), s.getDenominator()));
  354.         return Pair.create(STEP_TO_FRACTION.apply(converged.getKey()), converged.getValue());
  355.     }

  356.     /** {@inheritDoc} */
  357.     @Override
  358.     public double getReal() {
  359.         return doubleValue();
  360.     }

  361.     /**
  362.      * <p>
  363.      * Creates a {@code BigFraction} instance with the 2 parts of a fraction
  364.      * Y/Z.
  365.      * </p>
  366.      *
  367.      * <p>
  368.      * Any negative signs are resolved to be on the numerator.
  369.      * </p>
  370.      *
  371.      * @param numerator
  372.      *            the numerator, for example the three in 'three sevenths'.
  373.      * @param denominator
  374.      *            the denominator, for example the seven in 'three sevenths'.
  375.      * @return a new fraction instance, with the numerator and denominator
  376.      *         reduced.
  377.      * @throws ArithmeticException
  378.      *             if the denominator is <code>zero</code>.
  379.      */
  380.     public static BigFraction getReducedFraction(final int numerator,
  381.                                                  final int denominator) {
  382.         if (numerator == 0) {
  383.             return ZERO; // normalize zero.
  384.         }

  385.         return new BigFraction(numerator, denominator);
  386.     }

  387.     /**
  388.      * <p>
  389.      * Returns the absolute value of this {@link BigFraction}.
  390.      * </p>
  391.      *
  392.      * @return the absolute value as a {@link BigFraction}.
  393.      */
  394.     public BigFraction abs() {
  395.         return (numerator.signum() == 1) ? this : negate();
  396.     }

  397.     /** Check if a fraction is an integer.
  398.      * @return true of fraction is an integer
  399.      */
  400.     public boolean isInteger() {
  401.         return denominator.equals(BigInteger.ONE);
  402.     }

  403.     /** Returns the signum function of this {@link BigFraction}.
  404.      * <p>
  405.      * The return value is -1 if the specified value is negative;
  406.      * 0 if the specified value is zero; and 1 if the specified value is positive.
  407.      * </p>
  408.      * @return the signum function of this {@link BigFraction}
  409.      * @since 1.7
  410.      */
  411.     public int signum() {
  412.         return numerator.signum();
  413.     }

  414.     /**
  415.      * <p>
  416.      * Adds the value of this fraction to the passed {@link BigInteger},
  417.      * returning the result in reduced form.
  418.      * </p>
  419.      *
  420.      * @param bg
  421.      *            the {@link BigInteger} to add, must'nt be <code>null</code>.
  422.      * @return a {@code BigFraction} instance with the resulting values.
  423.      * @throws NullArgumentException
  424.      *             if the {@link BigInteger} is <code>null</code>.
  425.      */
  426.     public BigFraction add(final BigInteger bg) throws NullArgumentException {
  427.         MathUtils.checkNotNull(bg);

  428.         if (numerator.signum() == 0) {
  429.             return new BigFraction(bg);
  430.         }
  431.         if (bg.signum() == 0) {
  432.             return this;
  433.         }

  434.         return new BigFraction(numerator.add(denominator.multiply(bg)), denominator);
  435.     }

  436.     /**
  437.      * <p>
  438.      * Adds the value of this fraction to the passed {@code integer}, returning
  439.      * the result in reduced form.
  440.      * </p>
  441.      *
  442.      * @param i
  443.      *            the {@code integer} to add.
  444.      * @return a {@code BigFraction} instance with the resulting values.
  445.      */
  446.     public BigFraction add(final int i) {
  447.         return add(BigInteger.valueOf(i));
  448.     }

  449.     /**
  450.      * <p>
  451.      * Adds the value of this fraction to the passed {@code long}, returning
  452.      * the result in reduced form.
  453.      * </p>
  454.      *
  455.      * @param l
  456.      *            the {@code long} to add.
  457.      * @return a {@code BigFraction} instance with the resulting values.
  458.      */
  459.     public BigFraction add(final long l) {
  460.         return add(BigInteger.valueOf(l));
  461.     }

  462.     /**
  463.      * <p>
  464.      * Adds the value of this fraction to another, returning the result in
  465.      * reduced form.
  466.      * </p>
  467.      *
  468.      * @param fraction
  469.      *            the {@link BigFraction} to add, must not be <code>null</code>.
  470.      * @return a {@link BigFraction} instance with the resulting values.
  471.      * @throws NullArgumentException if the {@link BigFraction} is {@code null}.
  472.      */
  473.     @Override
  474.     public BigFraction add(final BigFraction fraction) {
  475.         MathUtils.checkNotNull(fraction, LocalizedCoreFormats.FRACTION);
  476.         if (fraction.numerator.signum() == 0) {
  477.             return this;
  478.         }
  479.         if (numerator.signum() == 0) {
  480.             return fraction;
  481.         }

  482.         BigInteger num;
  483.         BigInteger den;
  484.         if (denominator.equals(fraction.denominator)) {
  485.             num = numerator.add(fraction.numerator);
  486.             den = denominator;
  487.         } else {
  488.             num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator));
  489.             den = denominator.multiply(fraction.denominator);
  490.         }

  491.         if (num.signum() == 0) {
  492.             return ZERO;
  493.         }

  494.         return new BigFraction(num, den);

  495.     }

  496.     /**
  497.      * <p>
  498.      * Gets the fraction as a <code>BigDecimal</code>. This calculates the
  499.      * fraction as the numerator divided by denominator.
  500.      * </p>
  501.      *
  502.      * @return the fraction as a <code>BigDecimal</code>.
  503.      * @throws ArithmeticException
  504.      *             if the exact quotient does not have a terminating decimal
  505.      *             expansion.
  506.      * @see BigDecimal
  507.      */
  508.     public BigDecimal bigDecimalValue() {
  509.         return new BigDecimal(numerator).divide(new BigDecimal(denominator));
  510.     }

  511.     /**
  512.      * <p>
  513.      * Gets the fraction as a <code>BigDecimal</code> following the passed
  514.      * rounding mode. This calculates the fraction as the numerator divided by
  515.      * denominator.
  516.      * </p>
  517.      *
  518.      * @param roundingMode
  519.      *            rounding mode to apply. see {@link BigDecimal} constants.
  520.      * @return the fraction as a <code>BigDecimal</code>.
  521.      * @throws IllegalArgumentException
  522.      *             if {@code roundingMode} does not represent a valid rounding
  523.      *             mode.
  524.      * @see BigDecimal
  525.      */
  526.     public BigDecimal bigDecimalValue(final RoundingMode roundingMode) {
  527.         return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode);
  528.     }

  529.     /**
  530.      * <p>
  531.      * Gets the fraction as a <code>BigDecimal</code> following the passed scale
  532.      * and rounding mode. This calculates the fraction as the numerator divided
  533.      * by denominator.
  534.      * </p>
  535.      *
  536.      * @param scale
  537.      *            scale of the <code>BigDecimal</code> quotient to be returned.
  538.      *            see {@link BigDecimal} for more information.
  539.      * @param roundingMode
  540.      *            rounding mode to apply. see {@link BigDecimal} constants.
  541.      * @return the fraction as a <code>BigDecimal</code>.
  542.      * @see BigDecimal
  543.      */
  544.     public BigDecimal bigDecimalValue(final int scale, final RoundingMode roundingMode) {
  545.         return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode);
  546.     }

  547.     /**
  548.      * <p>
  549.      * Compares this object to another based on size.
  550.      * </p>
  551.      *
  552.      * @param object
  553.      *            the object to compare to, must not be <code>null</code>.
  554.      * @return -1 if this is less than {@code object}, +1 if this is greater
  555.      *         than {@code object}, 0 if they are equal.
  556.      * @see java.lang.Comparable#compareTo(java.lang.Object)
  557.      */
  558.     @Override
  559.     public int compareTo(final BigFraction object) {
  560.         int lhsSigNum = numerator.signum();
  561.         int rhsSigNum = object.numerator.signum();

  562.         if (lhsSigNum != rhsSigNum) {
  563.             return (lhsSigNum > rhsSigNum) ? 1 : -1;
  564.         }
  565.         if (lhsSigNum == 0) {
  566.             return 0;
  567.         }

  568.         BigInteger nOd = numerator.multiply(object.denominator);
  569.         BigInteger dOn = denominator.multiply(object.numerator);
  570.         return nOd.compareTo(dOn);
  571.     }

  572.     /**
  573.      * <p>
  574.      * Divide the value of this fraction by the passed {@code BigInteger},
  575.      * ie {@code this * 1 / bg}, returning the result in reduced form.
  576.      * </p>
  577.      *
  578.      * @param bg the {@code BigInteger} to divide by, must not be {@code null}
  579.      * @return a {@link BigFraction} instance with the resulting values
  580.      * @throws NullArgumentException if the {@code BigInteger} is {@code null}
  581.      * @throws MathRuntimeException if the fraction to divide by is zero
  582.      */
  583.     public BigFraction divide(final BigInteger bg) {
  584.         MathUtils.checkNotNull(bg);
  585.         if (bg.signum() == 0) {
  586.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  587.         }
  588.         if (numerator.signum() == 0) {
  589.             return ZERO;
  590.         }
  591.         return new BigFraction(numerator, denominator.multiply(bg));
  592.     }

  593.     /**
  594.      * <p>
  595.      * Divide the value of this fraction by the passed {@code int}, ie
  596.      * {@code this * 1 / i}, returning the result in reduced form.
  597.      * </p>
  598.      *
  599.      * @param i the {@code int} to divide by
  600.      * @return a {@link BigFraction} instance with the resulting values
  601.      * @throws MathRuntimeException if the fraction to divide by is zero
  602.      */
  603.     public BigFraction divide(final int i) {
  604.         return divide(BigInteger.valueOf(i));
  605.     }

  606.     /**
  607.      * <p>
  608.      * Divide the value of this fraction by the passed {@code long}, ie
  609.      * {@code this * 1 / l}, returning the result in reduced form.
  610.      * </p>
  611.      *
  612.      * @param l the {@code long} to divide by
  613.      * @return a {@link BigFraction} instance with the resulting values
  614.      * @throws MathRuntimeException if the fraction to divide by is zero
  615.      */
  616.     public BigFraction divide(final long l) {
  617.         return divide(BigInteger.valueOf(l));
  618.     }

  619.     /**
  620.      * <p>
  621.      * Divide the value of this fraction by another, returning the result in
  622.      * reduced form.
  623.      * </p>
  624.      *
  625.      * @param fraction Fraction to divide by, must not be {@code null}.
  626.      * @return a {@link BigFraction} instance with the resulting values.
  627.      * @throws NullArgumentException if the {@code fraction} is {@code null}.
  628.      * @throws MathRuntimeException if the fraction to divide by is zero
  629.      */
  630.     @Override
  631.     public BigFraction divide(final BigFraction fraction) {
  632.         MathUtils.checkNotNull(fraction, LocalizedCoreFormats.FRACTION);
  633.         if (fraction.numerator.signum() == 0) {
  634.             throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
  635.         }
  636.         if (numerator.signum() == 0) {
  637.             return ZERO;
  638.         }

  639.         return multiply(fraction.reciprocal());
  640.     }

  641.     /**
  642.      * <p>
  643.      * Gets the fraction as a {@code double}. This calculates the fraction as
  644.      * the numerator divided by denominator.
  645.      * </p>
  646.      *
  647.      * @return the fraction as a {@code double}
  648.      * @see java.lang.Number#doubleValue()
  649.      */
  650.     @Override
  651.     public double doubleValue() {
  652.         double result = numerator.doubleValue() / denominator.doubleValue();
  653.         if (Double.isInfinite(result) || Double.isNaN(result)) {
  654.             // Numerator and/or denominator must be out of range:
  655.             // Calculate how far to shift them to put them in range.
  656.             int shift = FastMath.max(numerator.bitLength(),
  657.                                      denominator.bitLength()) - FastMath.getExponent(Double.MAX_VALUE);
  658.             result = numerator.shiftRight(shift).doubleValue() /
  659.                 denominator.shiftRight(shift).doubleValue();
  660.         }
  661.         return result;
  662.     }

  663.     /**
  664.      * <p>
  665.      * Test for the equality of two fractions. If the lowest term numerator and
  666.      * denominators are the same for both fractions, the two fractions are
  667.      * considered to be equal.
  668.      * </p>
  669.      *
  670.      * @param other
  671.      *            fraction to test for equality to this fraction, can be
  672.      *            <code>null</code>.
  673.      * @return true if two fractions are equal, false if object is
  674.      *         <code>null</code>, not an instance of {@link BigFraction}, or not
  675.      *         equal to this fraction instance.
  676.      * @see java.lang.Object#equals(java.lang.Object)
  677.      */
  678.     @Override
  679.     public boolean equals(final Object other) {
  680.         boolean ret = false;

  681.         if (this == other) {
  682.             ret = true;
  683.         } else if (other instanceof BigFraction) {
  684.             BigFraction rhs = (BigFraction) other;
  685.             ret = numerator.equals(rhs.numerator) && denominator.equals(rhs.denominator);
  686.         }

  687.         return ret;
  688.     }

  689.     /**
  690.      * <p>
  691.      * Gets the fraction as a {@code float}. This calculates the fraction as
  692.      * the numerator divided by denominator.
  693.      * </p>
  694.      *
  695.      * @return the fraction as a {@code float}.
  696.      * @see java.lang.Number#floatValue()
  697.      */
  698.     @Override
  699.     public float floatValue() {
  700.         float result = numerator.floatValue() / denominator.floatValue();
  701.         if (Double.isNaN(result)) {
  702.             // Numerator and/or denominator must be out of range:
  703.             // Calculate how far to shift them to put them in range.
  704.             int shift = FastMath.max(numerator.bitLength(),
  705.                                      denominator.bitLength()) - FastMath.getExponent(Float.MAX_VALUE);
  706.             result = numerator.shiftRight(shift).floatValue() /
  707.                 denominator.shiftRight(shift).floatValue();
  708.         }
  709.         return result;
  710.     }

  711.     /**
  712.      * {@link java.math.BigInteger} number least common multiple.
  713.      *
  714.      * @param i0 first number
  715.      * @param i1 second number
  716.      * @return Least Common Multiple of both numbers
  717.      * @since 3.1
  718.      */
  719.     private static BigInteger lcm(final BigInteger i0, final BigInteger i1) {
  720.       if (i0.signum() == 0 && i1.signum() == 0) {
  721.         return BigInteger.ZERO;
  722.       }
  723.       BigInteger a = i0.abs();
  724.       BigInteger b = i1.abs();
  725.       BigInteger gcd = i0.gcd(b);
  726.       return (a.multiply(b)).divide(gcd);
  727.     }

  728.     /**
  729.      * Rational number greatest common divisor.
  730.      *
  731.      * @param s fraction.
  732.      * @return gcd(this, s).
  733.      * @since 3.1
  734.      */
  735.     public BigFraction gcd(BigFraction s) {
  736.       if (s.isZero()) {
  737.         return this;
  738.       }
  739.       if (this.isZero()) {
  740.         return s;
  741.       }
  742.       BigInteger p = numerator.gcd(s.numerator);
  743.       BigInteger q = lcm(denominator, s.denominator);
  744.       return new BigFraction(p, q);
  745.     }

  746.     /**
  747.      * Rational number least common multiple.
  748.      *
  749.      * @param s fraction.
  750.      * @return lcm(this, s).
  751.      * @since 3.1
  752.      */
  753.     public BigFraction lcm(BigFraction s) {
  754.       if (s.isZero()) {
  755.         return ZERO;
  756.       }
  757.       if (this.isZero()) {
  758.         return ZERO;
  759.       }
  760.       return new BigFraction(lcm(numerator, s.numerator), denominator.gcd(s.denominator));
  761.     }

  762.     /**
  763.      * <p>
  764.      * Access the denominator as a <code>BigInteger</code>.
  765.      * </p>
  766.      *
  767.      * @return the denominator as a <code>BigInteger</code>.
  768.      */
  769.     public BigInteger getDenominator() {
  770.         return denominator;
  771.     }

  772.     /**
  773.      * <p>
  774.      * Access the denominator as a {@code int}.
  775.      * </p>
  776.      *
  777.      * @return the denominator as a {@code int}.
  778.      */
  779.     public int getDenominatorAsInt() {
  780.         return denominator.intValue();
  781.     }

  782.     /**
  783.      * <p>
  784.      * Access the denominator as a {@code long}.
  785.      * </p>
  786.      *
  787.      * @return the denominator as a {@code long}.
  788.      */
  789.     public long getDenominatorAsLong() {
  790.         return denominator.longValue();
  791.     }

  792.     /**
  793.      * <p>
  794.      * Access the numerator as a <code>BigInteger</code>.
  795.      * </p>
  796.      *
  797.      * @return the numerator as a <code>BigInteger</code>.
  798.      */
  799.     public BigInteger getNumerator() {
  800.         return numerator;
  801.     }

  802.     /**
  803.      * <p>
  804.      * Access the numerator as a {@code int}.
  805.      * </p>
  806.      *
  807.      * @return the numerator as a {@code int}.
  808.      */
  809.     public int getNumeratorAsInt() {
  810.         return numerator.intValue();
  811.     }

  812.     /**
  813.      * <p>
  814.      * Access the numerator as a {@code long}.
  815.      * </p>
  816.      *
  817.      * @return the numerator as a {@code long}.
  818.      */
  819.     public long getNumeratorAsLong() {
  820.         return numerator.longValue();
  821.     }

  822.     /**
  823.      * <p>
  824.      * Gets a hashCode for the fraction.
  825.      * </p>
  826.      *
  827.      * @return a hash code value for this object.
  828.      * @see java.lang.Object#hashCode()
  829.      */
  830.     @Override
  831.     public int hashCode() {
  832.         return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode();
  833.     }

  834.     /**
  835.      * <p>
  836.      * Gets the fraction as an {@code int}. This returns the whole number part
  837.      * of the fraction.
  838.      * </p>
  839.      *
  840.      * @return the whole number fraction part.
  841.      * @see java.lang.Number#intValue()
  842.      */
  843.     @Override
  844.     public int intValue() {
  845.         return numerator.divide(denominator).intValue();
  846.     }

  847.     /**
  848.      * <p>
  849.      * Gets the fraction as a {@code long}. This returns the whole number part
  850.      * of the fraction.
  851.      * </p>
  852.      *
  853.      * @return the whole number fraction part.
  854.      * @see java.lang.Number#longValue()
  855.      */
  856.     @Override
  857.     public long longValue() {
  858.         return numerator.divide(denominator).longValue();
  859.     }

  860.     /**
  861.      * <p>
  862.      * Multiplies the value of this fraction by the passed
  863.      * <code>BigInteger</code>, returning the result in reduced form.
  864.      * </p>
  865.      *
  866.      * @param bg the {@code BigInteger} to multiply by.
  867.      * @return a {@code BigFraction} instance with the resulting values.
  868.      * @throws NullArgumentException if {@code bg} is {@code null}.
  869.      */
  870.     public BigFraction multiply(final BigInteger bg) {
  871.         MathUtils.checkNotNull(bg);
  872.         if (numerator.signum() == 0 || bg.signum() == 0) {
  873.             return ZERO;
  874.         }
  875.         return new BigFraction(bg.multiply(numerator), denominator);
  876.     }

  877.     /**
  878.      * <p>
  879.      * Multiply the value of this fraction by the passed {@code int}, returning
  880.      * the result in reduced form.
  881.      * </p>
  882.      *
  883.      * @param i
  884.      *            the {@code int} to multiply by.
  885.      * @return a {@link BigFraction} instance with the resulting values.
  886.      */
  887.     @Override
  888.     public BigFraction multiply(final int i) {
  889.         if (i == 0 || numerator.signum() == 0) {
  890.             return ZERO;
  891.         }

  892.         return multiply(BigInteger.valueOf(i));
  893.     }

  894.     /**
  895.      * <p>
  896.      * Multiply the value of this fraction by the passed {@code long},
  897.      * returning the result in reduced form.
  898.      * </p>
  899.      *
  900.      * @param l
  901.      *            the {@code long} to multiply by.
  902.      * @return a {@link BigFraction} instance with the resulting values.
  903.      */
  904.     public BigFraction multiply(final long l) {
  905.         if (l == 0 || numerator.signum() == 0) {
  906.             return ZERO;
  907.         }

  908.         return multiply(BigInteger.valueOf(l));
  909.     }

  910.     /**
  911.      * <p>
  912.      * Multiplies the value of this fraction by another, returning the result in
  913.      * reduced form.
  914.      * </p>
  915.      *
  916.      * @param fraction Fraction to multiply by, must not be {@code null}.
  917.      * @return a {@link BigFraction} instance with the resulting values.
  918.      * @throws NullArgumentException if {@code fraction} is {@code null}.
  919.      */
  920.     @Override
  921.     public BigFraction multiply(final BigFraction fraction) {
  922.         MathUtils.checkNotNull(fraction, LocalizedCoreFormats.FRACTION);
  923.         if (numerator.signum() == 0 ||
  924.             fraction.numerator.signum() == 0) {
  925.             return ZERO;
  926.         }
  927.         return new BigFraction(numerator.multiply(fraction.numerator),
  928.                                denominator.multiply(fraction.denominator));
  929.     }

  930.     /**
  931.      * <p>
  932.      * Return the additive inverse of this fraction, returning the result in
  933.      * reduced form.
  934.      * </p>
  935.      *
  936.      * @return the negation of this fraction.
  937.      */
  938.     @Override
  939.     public BigFraction negate() {
  940.         return new BigFraction(numerator.negate(), denominator);
  941.     }

  942.     /**
  943.      * <p>
  944.      * Gets the fraction percentage as a {@code double}. This calculates the
  945.      * fraction as the numerator divided by denominator multiplied by 100.
  946.      * </p>
  947.      *
  948.      * @return the fraction percentage as a {@code double}.
  949.      */
  950.     public double percentageValue() {
  951.         return multiply(ONE_HUNDRED).doubleValue();
  952.     }

  953.     /**
  954.      * <p>
  955.      * Returns a {@code BigFraction} whose value is
  956.      * {@code (this<sup>exponent</sup>)}, returning the result in reduced form.
  957.      * </p>
  958.      *
  959.      * @param exponent
  960.      *            exponent to which this {@code BigFraction} is to be
  961.      *            raised.
  962.      * @return this<sup>exponent</sup>
  963.      */
  964.     public BigFraction pow(final int exponent) {
  965.         if (exponent == 0) {
  966.             return ONE;
  967.         }
  968.         if (numerator.signum() == 0) {
  969.             return this;
  970.         }

  971.         if (exponent < 0) {
  972.             return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent));
  973.         }
  974.         return new BigFraction(numerator.pow(exponent), denominator.pow(exponent));
  975.     }

  976.     /**
  977.      * <p>
  978.      * Returns a {@code BigFraction} whose value is
  979.      * this<sup>exponent</sup>, returning the result in reduced form.
  980.      * </p>
  981.      *
  982.      * @param exponent
  983.      *            exponent to which this {@code BigFraction} is to be raised.
  984.      * @return this<sup>exponent</sup> as a {@code BigFraction}.
  985.      */
  986.     public BigFraction pow(final long exponent) {
  987.         if (exponent == 0) {
  988.             return ONE;
  989.         }
  990.         if (numerator.signum() == 0) {
  991.             return this;
  992.         }

  993.         if (exponent < 0) {
  994.             return new BigFraction(ArithmeticUtils.pow(denominator, -exponent),
  995.                                    ArithmeticUtils.pow(numerator,   -exponent));
  996.         }
  997.         return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
  998.                                ArithmeticUtils.pow(denominator, exponent));
  999.     }

  1000.     /**
  1001.      * <p>
  1002.      * Returns a {@code BigFraction} whose value is
  1003.      * this<sup>exponent</sup>, returning the result in reduced form.
  1004.      * </p>
  1005.      *
  1006.      * @param exponent
  1007.      *            exponent to which this {@code BigFraction} is to be raised.
  1008.      * @return this<sup>exponent</sup> as a {@code BigFraction}.
  1009.      */
  1010.     public BigFraction pow(final BigInteger exponent) {
  1011.         if (exponent.signum() == 0) {
  1012.             return ONE;
  1013.         }
  1014.         if (numerator.signum() == 0) {
  1015.             return this;
  1016.         }

  1017.         if (exponent.signum() == -1) {
  1018.             final BigInteger eNeg = exponent.negate();
  1019.             return new BigFraction(ArithmeticUtils.pow(denominator, eNeg),
  1020.                                    ArithmeticUtils.pow(numerator,   eNeg));
  1021.         }
  1022.         return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
  1023.                                ArithmeticUtils.pow(denominator, exponent));
  1024.     }

  1025.     /**
  1026.      * <p>
  1027.      * Returns a <code>double</code> whose value is
  1028.      * this<sup>exponent</sup>, returning the result in reduced form.
  1029.      * </p>
  1030.      *
  1031.      * @param exponent
  1032.      *            exponent to which this {@code BigFraction} is to be raised.
  1033.      * @return this<sup>exponent</sup>
  1034.      */
  1035.     public double pow(final double exponent) {
  1036.         return FastMath.pow(numerator.doubleValue(),   exponent) /
  1037.                FastMath.pow(denominator.doubleValue(), exponent);
  1038.     }

  1039.     /**
  1040.      * <p>
  1041.      * Return the multiplicative inverse of this fraction.
  1042.      * </p>
  1043.      *
  1044.      * @return the reciprocal fraction.
  1045.      */
  1046.     @Override
  1047.     public BigFraction reciprocal() {
  1048.         return new BigFraction(denominator, numerator);
  1049.     }

  1050.     /**
  1051.      * <p>
  1052.      * Reduce this {@code BigFraction} to its lowest terms.
  1053.      * </p>
  1054.      *
  1055.      * @return the reduced {@code BigFraction}. It doesn't change anything if
  1056.      *         the fraction can be reduced.
  1057.      */
  1058.     public BigFraction reduce() {
  1059.         final BigInteger gcd = numerator.gcd(denominator);

  1060.         if (BigInteger.ONE.compareTo(gcd) < 0) {
  1061.             return new BigFraction(numerator.divide(gcd), denominator.divide(gcd));
  1062.         } else {
  1063.             return this;
  1064.         }
  1065.     }

  1066.     /**
  1067.      * <p>
  1068.      * Subtracts the value of an {@link BigInteger} from the value of this
  1069.      * {@code BigFraction}, returning the result in reduced form.
  1070.      * </p>
  1071.      *
  1072.      * @param bg the {@link BigInteger} to subtract, cannot be {@code null}.
  1073.      * @return a {@code BigFraction} instance with the resulting values.
  1074.      * @throws NullArgumentException if the {@link BigInteger} is {@code null}.
  1075.      */
  1076.     public BigFraction subtract(final BigInteger bg) {
  1077.         MathUtils.checkNotNull(bg);
  1078.         if (bg.signum() == 0) {
  1079.             return this;
  1080.         }
  1081.         if (numerator.signum() == 0) {
  1082.             return new BigFraction(bg.negate());
  1083.         }

  1084.         return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator);
  1085.     }

  1086.     /**
  1087.      * <p>
  1088.      * Subtracts the value of an {@code integer} from the value of this
  1089.      * {@code BigFraction}, returning the result in reduced form.
  1090.      * </p>
  1091.      *
  1092.      * @param i the {@code integer} to subtract.
  1093.      * @return a {@code BigFraction} instance with the resulting values.
  1094.      */
  1095.     public BigFraction subtract(final int i) {
  1096.         return subtract(BigInteger.valueOf(i));
  1097.     }

  1098.     /**
  1099.      * <p>
  1100.      * Subtracts the value of a {@code long} from the value of this
  1101.      * {@code BigFraction}, returning the result in reduced form.
  1102.      * </p>
  1103.      *
  1104.      * @param l the {@code long} to subtract.
  1105.      * @return a {@code BigFraction} instance with the resulting values.
  1106.      */
  1107.     public BigFraction subtract(final long l) {
  1108.         return subtract(BigInteger.valueOf(l));
  1109.     }

  1110.     /**
  1111.      * <p>
  1112.      * Subtracts the value of another fraction from the value of this one,
  1113.      * returning the result in reduced form.
  1114.      * </p>
  1115.      *
  1116.      * @param fraction {@link BigFraction} to subtract, must not be {@code null}.
  1117.      * @return a {@link BigFraction} instance with the resulting values
  1118.      * @throws NullArgumentException if the {@code fraction} is {@code null}.
  1119.      */
  1120.     @Override
  1121.     public BigFraction subtract(final BigFraction fraction) {
  1122.         MathUtils.checkNotNull(fraction, LocalizedCoreFormats.FRACTION);
  1123.         if (fraction.numerator.signum() == 0) {
  1124.             return this;
  1125.         }
  1126.         if (numerator.signum() == 0) {
  1127.             return fraction.negate();
  1128.         }

  1129.         BigInteger num;
  1130.         BigInteger den;
  1131.         if (denominator.equals(fraction.denominator)) {
  1132.             num = numerator.subtract(fraction.numerator);
  1133.             den = denominator;
  1134.         } else {
  1135.             num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator));
  1136.             den = denominator.multiply(fraction.denominator);
  1137.         }
  1138.         return new BigFraction(num, den);

  1139.     }

  1140.     /**
  1141.      * <p>
  1142.      * Returns the <code>String</code> representing this fraction, ie
  1143.      * "num / dem" or just "num" if the denominator is one.
  1144.      * </p>
  1145.      *
  1146.      * @return a string representation of the fraction.
  1147.      * @see java.lang.Object#toString()
  1148.      */
  1149.     @Override
  1150.     public String toString() {
  1151.         if (BigInteger.ONE.equals(denominator)) {
  1152.             return numerator.toString();
  1153.         } else if (BigInteger.ZERO.equals(numerator)) {
  1154.             return "0";
  1155.         } else {
  1156.             return numerator + " / " + denominator;
  1157.         }
  1158.     }

  1159.     /** {@inheritDoc} */
  1160.     @Override
  1161.     public BigFractionField getField() {
  1162.         return BigFractionField.getInstance();
  1163.     }

  1164. }