fraction.java
来自「JAVA 文章管理系统源码」· Java 代码 · 共 795 行 · 第 1/2 页
JAVA
795 行
* <p>If the fraction is negative such as -7/4, it can be resolved into
* -1 3/4, so this method returns the positive proper numerator, 3.</p>
*
* @return the numerator fraction part of a proper fraction, always positive
*/
public int getProperNumerator() {
return Math.abs(numerator % denominator);
}
/**
* <p>Gets the proper whole part of the fraction.</p>
*
* <p>An improper fraction 7/4 can be resolved into a proper one, 1 3/4.
* This method returns the 1 from the proper fraction.</p>
*
* <p>If the fraction is negative such as -7/4, it can be resolved into
* -1 3/4, so this method returns the positive whole part -1.</p>
*
* @return the whole fraction part of a proper fraction, that includes the sign
*/
public int getProperWhole() {
return numerator / denominator;
}
// Number methods
//-------------------------------------------------------------------
/**
* <p>Gets the fraction as an <code>int</code>. This returns the whole number
* part of the fraction.</p>
*
* @return the whole number fraction part
*/
public int intValue() {
return numerator / denominator;
}
/**
* <p>Gets the fraction as a <code>long</code>. This returns the whole number
* part of the fraction.</p>
*
* @return the whole number fraction part
*/
public long longValue() {
return (long) numerator / denominator;
}
/**
* <p>Gets the fraction as a <code>float</code>. This calculates the fraction
* as the numerator divided by denominator.</p>
*
* @return the fraction as a <code>float</code>
*/
public float floatValue() {
return ((float) numerator) / ((float) denominator);
}
/**
* <p>Gets the fraction as a <code>double</code>. This calculates the fraction
* as the numerator divided by denominator.</p>
*
* @return the fraction as a <code>double</code>
*/
public double doubleValue() {
return ((double) numerator) / ((double) denominator);
}
// Calculations
//-------------------------------------------------------------------
/**
* <p>Reduce the fraction to the smallest values for the numerator and
* denominator, returning the result..</p>
*
* @return a new reduce fraction instance, or this if no simplification possible
*/
public Fraction reduce() {
int gcd = greatestCommonDivisor(Math.abs(numerator), denominator);
return Fraction.getFraction(numerator / gcd, denominator / gcd);
}
/**
* <p>Gets a fraction that is the invert (1/fraction) of this one.</p>
*
* <p>The returned fraction is not reduced.</p>
*
* @return a new fraction instance with the numerator and denominator inverted
* @throws ArithmeticException if the numerator is <code>zero</code>
*/
public Fraction invert() {
if (numerator == 0) {
throw new ArithmeticException("Unable to invert a fraction with a zero numerator");
}
return getFraction(denominator, numerator);
}
/**
* <p>Gets a fraction that is the negative (-fraction) of this one.</p>
*
* <p>The returned fraction is not reduced.</p>
*
* @return a new fraction instance with the opposite signed numerator
*/
public Fraction negate() {
return getFraction(-numerator, denominator);
}
/**
* <p>Gets a fraction that is the positive equivalent of this one.</p>
* <p>More precisely: <pre>(fraction >= 0 ? this : -fraction)</pre></p>
*
* <p>The returned fraction is not reduced.</p>
*
* @return <code>this</code> if it is positive, or a new positive fraction
* instance with the opposite signed numerator
*/
public Fraction abs() {
if (numerator >= 0) {
return this;
}
return getFraction(-numerator, denominator);
}
/**
* <p>Gets a fraction that is raised to the passed in power.</p>
*
* <p>The returned fraction is not reduced.</p>
*
* @param power the power to raise the fraction to
* @return <code>this</code> if the power is one, <code>ONE</code> if the power
* is zero (even if the fraction equals ZERO) or a new fraction instance
* raised to the appropriate power
* @throws ArithmeticException if the resulting numerator or denominator exceeds
* <code>Integer.MAX_VALUE</code>
*/
public Fraction pow(int power) {
if (power == 1) {
return this;
} else if (power == 0) {
return ONE;
} else {
double denominatorValue = Math.pow(denominator, power);
double numeratorValue = Math.pow(numerator, power);
if (numeratorValue > Integer.MAX_VALUE || denominatorValue > Integer.MAX_VALUE) {
throw new ArithmeticException("Integer overflow");
}
if (power < 0) {
return getFraction((int) Math.pow(denominator, -power),
(int) Math.pow(numerator, -power));
}
return getFraction((int) Math.pow(numerator, power),
(int) Math.pow(denominator, power));
}
}
/**
* <p>Gets the greatest common divisor of two numbers.</p>
*
* @param number1 a positive number
* @param number2 a positive number
* @return the greatest common divisor, never zero
*/
private static int greatestCommonDivisor(int number1, int number2) {
int remainder = number1 % number2;
while (remainder != 0) {
number1 = number2;
number2 = remainder;
remainder = number1 % number2;
}
return number2;
}
// Arithmetic
//-------------------------------------------------------------------
/**
* <p>Adds the value of this fraction to another, returning the result in
* reduced form.</p>
*
* @param fraction the fraction to add, must not be <code>null</code>
* @return a <code>Fraction</code> instance with the resulting values
* @throws IllegalArgumentException if the fraction is <code>null</code>
* @throws ArithmeticException if the resulting numerator or denominator exceeds
* <code>Integer.MAX_VALUE</code>
*/
public Fraction add(Fraction fraction) {
if (fraction == null) {
throw new IllegalArgumentException("The fraction must not be null");
}
if (numerator == 0) {
return fraction;
}
if (fraction.numerator == 0) {
return this;
}
// Compute lcd explicitly to limit overflow
int gcd = greatestCommonDivisor(Math.abs(fraction.denominator), Math.abs(denominator));
int thisResidue = denominator/gcd;
int thatResidue = fraction.denominator/gcd;
double denominatorValue = Math.abs((double) gcd * thisResidue * thatResidue);
double numeratorValue = (double) numerator * thatResidue + fraction.numerator * thisResidue;
if (Math.abs(numeratorValue) > Integer.MAX_VALUE ||
Math.abs(denominatorValue) > Integer.MAX_VALUE) {
throw new ArithmeticException("Integer overflow");
}
return Fraction.getReducedFraction((int) numeratorValue, (int) denominatorValue);
}
/**
* <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</code>
* @return a <code>Fraction</code> instance with the resulting values
* @throws IllegalArgumentException if the fraction is <code>null</code>
* @throws ArithmeticException if the resulting numerator or denominator exceeds
* <code>Integer.MAX_VALUE</code>
*/
public Fraction subtract(Fraction fraction) {
if (fraction == null) {
throw new IllegalArgumentException("The fraction must not be null");
}
return add(fraction.negate());
}
/**
* <p>Multiplies the value of this fraction by another, returning the result
* in reduced form.</p>
*
* @param fraction the fraction to multipy by, must not be <code>null</code>
* @return a <code>Fraction</code> instance with the resulting values
* @throws IllegalArgumentException if the fraction is <code>null</code>
* @throws ArithmeticException if the resulting numerator or denominator exceeds
* <code>Integer.MAX_VALUE</code>
*/
public Fraction multiplyBy(Fraction fraction) {
if (fraction == null) {
throw new IllegalArgumentException("The fraction must not be null");
}
if (numerator == 0 || fraction.numerator == 0) {
return ZERO;
}
double numeratorValue = (double) numerator * fraction.numerator;
double denominatorValue = (double) denominator * fraction.denominator;
if (Math.abs(numeratorValue) > Integer.MAX_VALUE ||
Math.abs(denominatorValue) > Integer.MAX_VALUE) {
throw new ArithmeticException("Integer overflow");
}
return getReducedFraction((int) numeratorValue, (int) denominatorValue);
}
/**
* <p>Divide the value of this fraction by another, returning the result
* in reduced form.</p>
*
* @param fraction the fraction to divide by, must not be <code>null</code>
* @return a <code>Fraction</code> instance with the resulting values
* @throws IllegalArgumentException if the fraction is <code>null</code>
* @throws ArithmeticException if the fraction to divide by is zero
* @throws ArithmeticException if the resulting numerator or denominator exceeds
* <code>Integer.MAX_VALUE</code>
*/
public Fraction divideBy(Fraction fraction) {
if (fraction == null) {
throw new IllegalArgumentException("The fraction must not be null");
}
if (fraction.numerator == 0) {
throw new ArithmeticException("The fraction to divide by must not be zero");
}
if (numerator == 0) {
return ZERO;
}
double numeratorValue = (double) numerator * fraction.denominator;
double denominatorValue = (double) denominator * fraction.numerator;
if (Math.abs(numeratorValue) > Integer.MAX_VALUE ||
Math.abs(denominatorValue) > Integer.MAX_VALUE) {
throw new ArithmeticException("Integer overflow");
}
return getReducedFraction((int) numeratorValue, (int) denominatorValue);
}
// Basics
//-------------------------------------------------------------------
/**
* <p>Compares this fraction to another object to test if they are equal.</p>.
*
* <p>To be equal, both values must be equal. Thus 2/4 is not equal to 1/2.</p>
*
* @param obj the reference object with which to compare
* @return <code>true</code> if this object is equal
*/
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Fraction == false) {
return false;
}
Fraction other = (Fraction) obj;
return (numerator == other.numerator &&
denominator == other.denominator);
}
/**
* <p>Gets a hashCode for the fraction.</p>
*
* @return a hash code value for this object
*/
public int hashCode() {
if (hashCode == 0) {
hashCode = 17;
hashCode = 37 * hashCode + numerator;
hashCode = 37 * hashCode + denominator;
}
return hashCode;
}
/**
* <p>Compares this object to another based on size.</p>
*
* @param object the object to compare to
* @return -1 if this is less, 0 if equal, +1 if greater
* @throws ClassCastException if the object is not a <code>Fraction</code>
* @throws NullPointerException if the object is <code>null</code>
*/
public int compareTo(Object object) {
Fraction other = (Fraction) object;
if (numerator == other.numerator && denominator == other.denominator) {
return 0;
}
// otherwise see which is less
long first = (long) numerator * (long) other.denominator;
long second = (long) other.numerator * (long) denominator;
if (first == second) {
return 0;
} else if (first < second) {
return -1;
} else {
return 1;
}
}
/**
* <p>Gets the fraction as a <code>String</code>.</p>
*
* <p>The format used is '<i>numerator</i>/<i>denominator</i>' always.
*
* @return a <code>String</code> form of the fraction
*/
public String toString() {
if (toString == null) {
toString = new StringBuffer(32)
.append(numerator)
.append('/')
.append(denominator).toString();
}
return toString;
}
/**
* <p>Gets the fraction as a proper <code>String</code> in the format X Y/Z.</p>
*
* <p>The format used in '<i>wholeNumber</i> <i>numerator</i>/<i>denominator</i>'.
* If the whole number is zero it will be ommitted. If the numerator is zero,
* only the whole number is returned.</p>
*
* @return a <code>String</code> form of the fraction
*/
public String toProperString() {
if (toProperString == null) {
if (numerator == 0) {
toProperString = "0";
} else if (numerator == denominator) {
toProperString = "1";
} else if (Math.abs(numerator) > denominator) {
int properNumerator = getProperNumerator();
if (properNumerator == 0) {
toProperString = Integer.toString(getProperWhole());
} else {
toProperString = new StringBuffer(32)
.append(getProperWhole()).append(' ')
.append(properNumerator).append('/')
.append(denominator).toString();
}
} else {
toProperString = new StringBuffer(32)
.append(numerator).append('/')
.append(denominator).toString();
}
}
return toProperString;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?