/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.fraction;
import java.io.Serializable;
import java.math.BigInteger;
import org.apache.commons.math3.FieldElement;
import org.apache.commons.math3.exception.util.LocalizedFormats;
import org.apache.commons.math3.exception.MathArithmeticException;
import org.apache.commons.math3.exception.NullArgumentException;
import org.apache.commons.math3.util.ArithmeticUtils;
import org.apache.commons.math3.util.FastMath;
Representation of a rational number.
implements Serializable since 2.0
Since: 1.1
/**
* Representation of a rational number.
*
* implements Serializable since 2.0
*
* @since 1.1
*/
public class Fraction
extends Number
implements FieldElement<Fraction>, Comparable<Fraction>, Serializable {
A fraction representing "2 / 1". /** A fraction representing "2 / 1". */
public static final Fraction TWO = new Fraction(2, 1);
A fraction representing "1". /** A fraction representing "1". */
public static final Fraction ONE = new Fraction(1, 1);
A fraction representing "0". /** A fraction representing "0". */
public static final Fraction ZERO = new Fraction(0, 1);
A fraction representing "4/5". /** A fraction representing "4/5". */
public static final Fraction FOUR_FIFTHS = new Fraction(4, 5);
A fraction representing "1/5". /** A fraction representing "1/5". */
public static final Fraction ONE_FIFTH = new Fraction(1, 5);
A fraction representing "1/2". /** A fraction representing "1/2". */
public static final Fraction ONE_HALF = new Fraction(1, 2);
A fraction representing "1/4". /** A fraction representing "1/4". */
public static final Fraction ONE_QUARTER = new Fraction(1, 4);
A fraction representing "1/3". /** A fraction representing "1/3". */
public static final Fraction ONE_THIRD = new Fraction(1, 3);
A fraction representing "3/5". /** A fraction representing "3/5". */
public static final Fraction THREE_FIFTHS = new Fraction(3, 5);
A fraction representing "3/4". /** A fraction representing "3/4". */
public static final Fraction THREE_QUARTERS = new Fraction(3, 4);
A fraction representing "2/5". /** A fraction representing "2/5". */
public static final Fraction TWO_FIFTHS = new Fraction(2, 5);
A fraction representing "2/4". /** A fraction representing "2/4". */
public static final Fraction TWO_QUARTERS = new Fraction(2, 4);
A fraction representing "2/3". /** A fraction representing "2/3". */
public static final Fraction TWO_THIRDS = new Fraction(2, 3);
A fraction representing "-1 / 1". /** A fraction representing "-1 / 1". */
public static final Fraction MINUS_ONE = new Fraction(-1, 1);
Serializable version identifier /** Serializable version identifier */
private static final long serialVersionUID = 3698073679419233275L;
The default epsilon used for convergence. /** The default epsilon used for convergence. */
private static final double DEFAULT_EPSILON = 1e-5;
The denominator. /** The denominator. */
private final int denominator;
The numerator. /** The numerator. */
private final int numerator;
Create a fraction given the double value.
Params: - value – the double value to convert to a fraction.
Throws: - FractionConversionException – if the continued fraction failed to
converge.
/**
* Create a fraction given the double value.
* @param value the double value to convert to a fraction.
* @throws FractionConversionException if the continued fraction failed to
* converge.
*/
public Fraction(double value) throws FractionConversionException {
this(value, DEFAULT_EPSILON, 100);
}
Create a fraction given the double value and maximum error allowed.
References:
-
Continued Fraction equations (11) and (22)-(26)
Params: - value – the double value to convert to a fraction.
- epsilon – maximum error allowed. The resulting fraction is within
epsilon
of value
, in absolute terms. - maxIterations – maximum number of convergents
Throws: - FractionConversionException – if the continued fraction failed to
converge.
/**
* Create a fraction given the double value and maximum error allowed.
* <p>
* References:
* <ul>
* <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
* Continued Fraction</a> equations (11) and (22)-(26)</li>
* </ul>
* </p>
* @param value the double value to convert to a fraction.
* @param epsilon maximum error allowed. The resulting fraction is within
* {@code epsilon} of {@code value}, in absolute terms.
* @param maxIterations maximum number of convergents
* @throws FractionConversionException if the continued fraction failed to
* converge.
*/
public Fraction(double value, double epsilon, int maxIterations)
throws FractionConversionException
{
this(value, epsilon, Integer.MAX_VALUE, maxIterations);
}
Create a fraction given the double value and maximum denominator.
References:
-
Continued Fraction equations (11) and (22)-(26)
Params: - value – the double value to convert to a fraction.
- maxDenominator – The maximum allowed value for denominator
Throws: - FractionConversionException – if the continued fraction failed to
converge
/**
* Create a fraction given the double value and maximum denominator.
* <p>
* References:
* <ul>
* <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
* Continued Fraction</a> equations (11) and (22)-(26)</li>
* </ul>
* </p>
* @param value the double value to convert to a fraction.
* @param maxDenominator The maximum allowed value for denominator
* @throws FractionConversionException if the continued fraction failed to
* converge
*/
public Fraction(double value, int maxDenominator)
throws FractionConversionException
{
this(value, 0, maxDenominator, 100);
}
Create a fraction given the double value and either the maximum error
allowed or the maximum number of denominator digits.
NOTE: This constructor is called with EITHER
- a valid epsilon value and the maxDenominator set to Integer.MAX_VALUE
(that way the maxDenominator has no effect).
OR
- a valid maxDenominator value and the epsilon value set to zero
(that way epsilon only has effect if there is an exact match before
the maxDenominator value is reached).
It has been done this way so that the same code can be (re)used for both
scenarios. However this could be confusing to users if it were part of
the public API and this constructor should therefore remain PRIVATE.
See JIRA issue ticket MATH-181 for more details:
https://issues.apache.org/jira/browse/MATH-181
Params: - value – the double value to convert to a fraction.
- epsilon – maximum error allowed. The resulting fraction is within
epsilon
of value
, in absolute terms. - maxDenominator – maximum denominator value allowed.
- maxIterations – maximum number of convergents
Throws: - FractionConversionException – if the continued fraction failed to
converge.
/**
* Create a fraction given the double value and either the maximum error
* allowed or the maximum number of denominator digits.
* <p>
*
* NOTE: This constructor is called with EITHER
* - a valid epsilon value and the maxDenominator set to Integer.MAX_VALUE
* (that way the maxDenominator has no effect).
* OR
* - a valid maxDenominator value and the epsilon value set to zero
* (that way epsilon only has effect if there is an exact match before
* the maxDenominator value is reached).
* </p><p>
*
* It has been done this way so that the same code can be (re)used for both
* scenarios. However this could be confusing to users if it were part of
* the public API and this constructor should therefore remain PRIVATE.
* </p>
*
* See JIRA issue ticket MATH-181 for more details:
*
* https://issues.apache.org/jira/browse/MATH-181
*
* @param value the double value to convert to a fraction.
* @param epsilon maximum error allowed. The resulting fraction is within
* {@code epsilon} of {@code value}, in absolute terms.
* @param maxDenominator maximum denominator value allowed.
* @param maxIterations maximum number of convergents
* @throws FractionConversionException if the continued fraction failed to
* converge.
*/
private Fraction(double value, double epsilon, int maxDenominator, int maxIterations)
throws FractionConversionException
{
long overflow = Integer.MAX_VALUE;
double r0 = value;
long a0 = (long)FastMath.floor(r0);
if (FastMath.abs(a0) > overflow) {
throw new FractionConversionException(value, a0, 1l);
}
// check for (almost) integer arguments, which should not go to iterations.
if (FastMath.abs(a0 - value) < epsilon) {
this.numerator = (int) a0;
this.denominator = 1;
return;
}
long p0 = 1;
long q0 = 0;
long p1 = a0;
long q1 = 1;
long p2 = 0;
long q2 = 1;
int n = 0;
boolean stop = false;
do {
++n;
double r1 = 1.0 / (r0 - a0);
long a1 = (long)FastMath.floor(r1);
p2 = (a1 * p1) + p0;
q2 = (a1 * q1) + q0;
if ((FastMath.abs(p2) > overflow) || (FastMath.abs(q2) > overflow)) {
// in maxDenominator mode, if the last fraction was very close to the actual value
// q2 may overflow in the next iteration; in this case return the last one.
if (epsilon == 0.0 && FastMath.abs(q1) < maxDenominator) {
break;
}
throw new FractionConversionException(value, p2, q2);
}
double convergent = (double)p2 / (double)q2;
if (n < maxIterations && FastMath.abs(convergent - value) > epsilon && q2 < maxDenominator) {
p0 = p1;
p1 = p2;
q0 = q1;
q1 = q2;
a0 = a1;
r0 = r1;
} else {
stop = true;
}
} while (!stop);
if (n >= maxIterations) {
throw new FractionConversionException(value, maxIterations);
}
if (q2 < maxDenominator) {
this.numerator = (int) p2;
this.denominator = (int) q2;
} else {
this.numerator = (int) p1;
this.denominator = (int) q1;
}
}
Create a fraction from an int.
The fraction is num / 1.
Params: - num – the numerator.
/**
* Create a fraction from an int.
* The fraction is num / 1.
* @param num the numerator.
*/
public Fraction(int num) {
this(num, 1);
}
Create a fraction given the numerator and denominator. The fraction is
reduced to lowest terms.
Params: - num – the numerator.
- den – the denominator.
Throws: - MathArithmeticException – if the denominator is
zero
/**
* Create a fraction given the numerator and denominator. The fraction is
* reduced to lowest terms.
* @param num the numerator.
* @param den the denominator.
* @throws MathArithmeticException if the denominator is {@code zero}
*/
public Fraction(int num, int den) {
if (den == 0) {
throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR_IN_FRACTION,
num, den);
}
if (den < 0) {
if (num == Integer.MIN_VALUE ||
den == Integer.MIN_VALUE) {
throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_FRACTION,
num, den);
}
num = -num;
den = -den;
}
// reduce numerator and denominator by greatest common denominator.
final int d = ArithmeticUtils.gcd(num, den);
if (d > 1) {
num /= d;
den /= d;
}
// move sign to numerator.
if (den < 0) {
num = -num;
den = -den;
}
this.numerator = num;
this.denominator = den;
}
Returns the absolute value of this fraction.
Returns: the absolute value.
/**
* Returns the absolute value of this fraction.
* @return the absolute value.
*/
public Fraction abs() {
Fraction ret;
if (numerator >= 0) {
ret = this;
} else {
ret = negate();
}
return ret;
}
Compares this object to another based on size.
Params: - object – the object to compare to
Returns: -1 if this is less than object
, +1 if this is greater than object
, 0 if they are equal.
/**
* Compares this object to another based on size.
* @param object the object to compare to
* @return -1 if this is less than {@code object}, +1 if this is greater
* than {@code object}, 0 if they are equal.
*/
public int compareTo(Fraction object) {
long nOd = ((long) numerator) * object.denominator;
long dOn = ((long) denominator) * object.numerator;
return (nOd < dOn) ? -1 : ((nOd > dOn) ? +1 : 0);
}
Gets the fraction as a double
. This calculates the fraction as the numerator divided by denominator. Returns: the fraction as a double
/**
* Gets the fraction as a {@code double}. This calculates the fraction as
* the numerator divided by denominator.
* @return the fraction as a {@code double}
*/
@Override
public double doubleValue() {
return (double)numerator / (double)denominator;
}
Test for the equality of two fractions. If the lowest term
numerator and denominators are the same for both fractions, the two
fractions are considered to be equal.
Params: - other – fraction to test for equality to this fraction
Returns: true if two fractions are equal, false if object is null
, not an instance of Fraction
, or not equal to this fraction instance.
/**
* Test for the equality of two fractions. If the lowest term
* numerator and denominators are the same for both fractions, the two
* fractions are considered to be equal.
* @param other fraction to test for equality to this fraction
* @return true if two fractions are equal, false if object is
* {@code null}, not an instance of {@link Fraction}, or not equal
* to this fraction instance.
*/
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other instanceof Fraction) {
// since fractions are always in lowest terms, numerators and
// denominators can be compared directly for equality.
Fraction rhs = (Fraction)other;
return (numerator == rhs.numerator) &&
(denominator == rhs.denominator);
}
return false;
}
Gets the fraction as a float
. This calculates the fraction as the numerator divided by denominator. Returns: the fraction as a float
/**
* Gets the fraction as a {@code float}. This calculates the fraction as
* the numerator divided by denominator.
* @return the fraction as a {@code float}
*/
@Override
public float floatValue() {
return (float)doubleValue();
}
Access the denominator.
Returns: the denominator.
/**
* Access the denominator.
* @return the denominator.
*/
public int getDenominator() {
return denominator;
}
Access the numerator.
Returns: the numerator.
/**
* Access the numerator.
* @return the numerator.
*/
public int getNumerator() {
return numerator;
}
Gets a hashCode for the fraction.
Returns: a hash code value for this object
/**
* Gets a hashCode for the fraction.
* @return a hash code value for this object
*/
@Override
public int hashCode() {
return 37 * (37 * 17 + numerator) + denominator;
}
Gets the fraction as an int
. This returns the whole number part of the fraction. Returns: the whole number fraction part
/**
* Gets the fraction as an {@code int}. This returns the whole number part
* of the fraction.
* @return the whole number fraction part
*/
@Override
public int intValue() {
return (int)doubleValue();
}
Gets the fraction as a long
. This returns the whole number part of the fraction. Returns: the whole number fraction part
/**
* Gets the fraction as a {@code long}. This returns the whole number part
* of the fraction.
* @return the whole number fraction part
*/
@Override
public long longValue() {
return (long)doubleValue();
}
Return the additive inverse of this fraction.
Returns: the negation of this fraction.
/**
* Return the additive inverse of this fraction.
* @return the negation of this fraction.
*/
public Fraction negate() {
if (numerator==Integer.MIN_VALUE) {
throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_FRACTION, numerator, denominator);
}
return new Fraction(-numerator, denominator);
}
Return the multiplicative inverse of this fraction.
Returns: the reciprocal fraction
/**
* Return the multiplicative inverse of this fraction.
* @return the reciprocal fraction
*/
public Fraction reciprocal() {
return new Fraction(denominator, numerator);
}
Adds the value of this fraction to another, returning the result in reduced form.
The algorithm follows Knuth, 4.5.1.
Params: - fraction – the fraction to add, must not be
null
Throws: - NullArgumentException – if the fraction is
null
- MathArithmeticException – if the resulting numerator or denominator exceeds
Integer.MAX_VALUE
Returns: a Fraction
instance with the resulting values
/**
* <p>Adds the value of this fraction to another, returning the result in reduced form.
* The algorithm follows Knuth, 4.5.1.</p>
*
* @param fraction the fraction to add, must not be {@code null}
* @return a {@code Fraction} instance with the resulting values
* @throws NullArgumentException if the fraction is {@code null}
* @throws MathArithmeticException if the resulting numerator or denominator exceeds
* {@code Integer.MAX_VALUE}
*/
public Fraction add(Fraction fraction) {
return addSub(fraction, true /* add */);
}
Add an integer to the fraction.
Params: - i – the
integer
to add.
Returns: this + i
/**
* Add an integer to the fraction.
* @param i the {@code integer} to add.
* @return this + i
*/
public Fraction add(final int i) {
return new Fraction(numerator + i * denominator, denominator);
}
Subtracts the value of another fraction from the value of this one,
returning the result in reduced form.
Params: - fraction – the fraction to subtract, must not be
null
Throws: - NullArgumentException – if the fraction is
null
- MathArithmeticException – if the resulting numerator or denominator cannot be represented in an
int
.
Returns: a Fraction
instance with the resulting values
/**
* <p>Subtracts the value of another fraction from the value of this one,
* returning the result in reduced form.</p>
*
* @param fraction the fraction to subtract, must not be {@code null}
* @return a {@code Fraction} instance with the resulting values
* @throws NullArgumentException if the fraction is {@code null}
* @throws MathArithmeticException if the resulting numerator or denominator
* cannot be represented in an {@code int}.
*/
public Fraction subtract(Fraction fraction) {
return addSub(fraction, false /* subtract */);
}
Subtract an integer from the fraction.
Params: - i – the
integer
to subtract.
Returns: this - i
/**
* Subtract an integer from the fraction.
* @param i the {@code integer} to subtract.
* @return this - i
*/
public Fraction subtract(final int i) {
return new Fraction(numerator - i * denominator, denominator);
}
Implement add and subtract using algorithm described in Knuth 4.5.1.
Params: - fraction – the fraction to subtract, must not be
null
- isAdd – true to add, false to subtract
Throws: - NullArgumentException – if the fraction is
null
- MathArithmeticException – if the resulting numerator or denominator cannot be represented in an
int
.
Returns: a Fraction
instance with the resulting values
/**
* Implement add and subtract using algorithm described in Knuth 4.5.1.
*
* @param fraction the fraction to subtract, must not be {@code null}
* @param isAdd true to add, false to subtract
* @return a {@code Fraction} instance with the resulting values
* @throws NullArgumentException if the fraction is {@code null}
* @throws MathArithmeticException if the resulting numerator or denominator
* cannot be represented in an {@code int}.
*/
private Fraction addSub(Fraction fraction, boolean isAdd) {
if (fraction == null) {
throw new NullArgumentException(LocalizedFormats.FRACTION);
}
// zero is identity for addition.
if (numerator == 0) {
return isAdd ? fraction : fraction.negate();
}
if (fraction.numerator == 0) {
return this;
}
// if denominators are randomly distributed, d1 will be 1 about 61%
// of the time.
int d1 = ArithmeticUtils.gcd(denominator, fraction.denominator);
if (d1==1) {
// result is ( (u*v' +/- u'v) / u'v')
int uvp = ArithmeticUtils.mulAndCheck(numerator, fraction.denominator);
int upv = ArithmeticUtils.mulAndCheck(fraction.numerator, denominator);
return new Fraction
(isAdd ? ArithmeticUtils.addAndCheck(uvp, upv) :
ArithmeticUtils.subAndCheck(uvp, upv),
ArithmeticUtils.mulAndCheck(denominator, fraction.denominator));
}
// the quantity 't' requires 65 bits of precision; see knuth 4.5.1
// exercise 7. we're going to use a BigInteger.
// t = u(v'/d1) +/- v(u'/d1)
BigInteger uvp = BigInteger.valueOf(numerator)
.multiply(BigInteger.valueOf(fraction.denominator/d1));
BigInteger upv = BigInteger.valueOf(fraction.numerator)
.multiply(BigInteger.valueOf(denominator/d1));
BigInteger t = isAdd ? uvp.add(upv) : uvp.subtract(upv);
// but d2 doesn't need extra precision because
// d2 = gcd(t,d1) = gcd(t mod d1, d1)
int tmodd1 = t.mod(BigInteger.valueOf(d1)).intValue();
int d2 = (tmodd1==0)?d1:ArithmeticUtils.gcd(tmodd1, d1);
// result is (t/d2) / (u'/d1)(v'/d2)
BigInteger w = t.divide(BigInteger.valueOf(d2));
if (w.bitLength() > 31) {
throw new MathArithmeticException(LocalizedFormats.NUMERATOR_OVERFLOW_AFTER_MULTIPLY,
w);
}
return new Fraction (w.intValue(),
ArithmeticUtils.mulAndCheck(denominator/d1,
fraction.denominator/d2));
}
Multiplies the value of this fraction by another, returning the
result in reduced form.
Params: - fraction – the fraction to multiply by, must not be
null
Throws: - NullArgumentException – if the fraction is
null
- MathArithmeticException – if the resulting numerator or denominator exceeds
Integer.MAX_VALUE
Returns: a Fraction
instance with the resulting values
/**
* <p>Multiplies the value of this fraction by another, returning the
* result in reduced form.</p>
*
* @param fraction the fraction to multiply by, must not be {@code null}
* @return a {@code Fraction} instance with the resulting values
* @throws NullArgumentException if the fraction is {@code null}
* @throws MathArithmeticException if the resulting numerator or denominator exceeds
* {@code Integer.MAX_VALUE}
*/
public Fraction multiply(Fraction fraction) {
if (fraction == null) {
throw new NullArgumentException(LocalizedFormats.FRACTION);
}
if (numerator == 0 || fraction.numerator == 0) {
return ZERO;
}
// knuth 4.5.1
// make sure we don't overflow unless the result *must* overflow.
int d1 = ArithmeticUtils.gcd(numerator, fraction.denominator);
int d2 = ArithmeticUtils.gcd(fraction.numerator, denominator);
return getReducedFraction
(ArithmeticUtils.mulAndCheck(numerator/d1, fraction.numerator/d2),
ArithmeticUtils.mulAndCheck(denominator/d2, fraction.denominator/d1));
}
Multiply the fraction by an integer.
Params: - i – the
integer
to multiply by.
Returns: this * i
/**
* Multiply the fraction by an integer.
* @param i the {@code integer} to multiply by.
* @return this * i
*/
public Fraction multiply(final int i) {
return multiply(new Fraction(i));
}
Divide the value of this fraction by another.
Params: - fraction – the fraction to divide by, must not be
null
Throws: - IllegalArgumentException – if the fraction is
null
- MathArithmeticException – if the fraction to divide by is zero
- MathArithmeticException – if the resulting numerator or denominator exceeds
Integer.MAX_VALUE
Returns: a Fraction
instance with the resulting values
/**
* <p>Divide the value of this fraction by another.</p>
*
* @param fraction the fraction to divide by, must not be {@code null}
* @return a {@code Fraction} instance with the resulting values
* @throws IllegalArgumentException if the fraction is {@code null}
* @throws MathArithmeticException if the fraction to divide by is zero
* @throws MathArithmeticException if the resulting numerator or denominator exceeds
* {@code Integer.MAX_VALUE}
*/
public Fraction divide(Fraction fraction) {
if (fraction == null) {
throw new NullArgumentException(LocalizedFormats.FRACTION);
}
if (fraction.numerator == 0) {
throw new MathArithmeticException(LocalizedFormats.ZERO_FRACTION_TO_DIVIDE_BY,
fraction.numerator, fraction.denominator);
}
return multiply(fraction.reciprocal());
}
Divide the fraction by an integer.
Params: - i – the
integer
to divide by.
Returns: this * i
/**
* Divide the fraction by an integer.
* @param i the {@code integer} to divide by.
* @return this * i
*/
public Fraction divide(final int i) {
return divide(new Fraction(i));
}
Gets the fraction percentage as a double
. This calculates the fraction as the numerator divided by denominator multiplied by 100.
Returns: the fraction percentage as a double
.
/**
* <p>
* Gets the fraction percentage as a {@code double}. This calculates the
* fraction as the numerator divided by denominator multiplied by 100.
* </p>
*
* @return the fraction percentage as a {@code double}.
*/
public double percentageValue() {
return 100 * doubleValue();
}
Creates a Fraction
instance with the 2 parts of a fraction Y/Z.
Any negative signs are resolved to be on the numerator.
Params: - numerator – the numerator, for example the three in 'three sevenths'
- denominator – the denominator, for example the seven in 'three sevenths'
Throws: - MathArithmeticException – if the denominator is
zero
Returns: a new fraction instance, with the numerator and denominator reduced
/**
* <p>Creates a {@code Fraction} instance with the 2 parts
* of a fraction Y/Z.</p>
*
* <p>Any negative signs are resolved to be on the numerator.</p>
*
* @param numerator the numerator, for example the three in 'three sevenths'
* @param denominator the denominator, for example the seven in 'three sevenths'
* @return a new fraction instance, with the numerator and denominator reduced
* @throws MathArithmeticException if the denominator is {@code zero}
*/
public static Fraction getReducedFraction(int numerator, int denominator) {
if (denominator == 0) {
throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR_IN_FRACTION,
numerator, denominator);
}
if (numerator==0) {
return ZERO; // normalize zero.
}
// allow 2^k/-2^31 as a valid fraction (where k>0)
if (denominator==Integer.MIN_VALUE && (numerator&1)==0) {
numerator/=2; denominator/=2;
}
if (denominator < 0) {
if (numerator==Integer.MIN_VALUE ||
denominator==Integer.MIN_VALUE) {
throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_FRACTION,
numerator, denominator);
}
numerator = -numerator;
denominator = -denominator;
}
// simplify fraction.
int gcd = ArithmeticUtils.gcd(numerator, denominator);
numerator /= gcd;
denominator /= gcd;
return new Fraction(numerator, denominator);
}
Returns the String
representing this fraction, ie "num / dem" or just "num" if the denominator is one.
See Also: Returns: a string representation of the fraction.
/**
* <p>
* Returns the {@code String} representing this fraction, ie
* "num / dem" or just "num" if the denominator is one.
* </p>
*
* @return a string representation of the fraction.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
String str = null;
if (denominator == 1) {
str = Integer.toString(numerator);
} else if (numerator == 0) {
str = "0";
} else {
str = numerator + " / " + denominator;
}
return str;
}
{@inheritDoc} /** {@inheritDoc} */
public FractionField getField() {
return FractionField.getInstance();
}
}