1210 lines
26 KiB
Java
1210 lines
26 KiB
Java
//******************************************************************************
|
|
//
|
|
// File: Rational.java
|
|
// Package: edu.rit.numeric
|
|
// Unit: Class edu.rit.numeric.Rational
|
|
//
|
|
// This Java source file is copyright (C) 2013 by Alan Kaminsky. All rights
|
|
// reserved. For further information, contact the author, Alan Kaminsky, at
|
|
// ark@cs.rit.edu.
|
|
//
|
|
// This Java source file is part of the Parallel Java 2 Library ("PJ2"). PJ2 is
|
|
// free software; you can redistribute it and/or modify it under the terms of
|
|
// the GNU General Public License as published by the Free Software Foundation;
|
|
// either version 3 of the License, or (at your option) any later version.
|
|
//
|
|
// PJ2 is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
//
|
|
// A copy of the GNU General Public License is provided in the file gpl.txt. You
|
|
// may also obtain a copy of the GNU General Public License on the World Wide
|
|
// Web at http://www.gnu.org/licenses/gpl.html.
|
|
//
|
|
//******************************************************************************
|
|
|
|
package edu.rit.numeric;
|
|
|
|
import java.io.Serializable;
|
|
|
|
/**
|
|
* Class Rational provides a 32-bit rational number. A 32-bit rational number is
|
|
* the ratio of two 32-bit integers (type <TT>int</TT>). Operations are provided
|
|
* for exact arithmetic and comparison with rational numbers.
|
|
* <P>
|
|
* Class Rational overrides the <TT>equals()</TT> and <TT>hashCode()</TT>
|
|
* methods, making it suitable for use as a key in a hashed data structure like
|
|
* a {@link java.util.HashMap </CODE>HashMap<CODE>} or {@link java.util.HashSet
|
|
* </CODE>HashSet<CODE>}. However, a Rational object is mutable. Take care not
|
|
* to change the value of a Rational object if it is used as a key in a hashed
|
|
* data structure.
|
|
* <P>
|
|
* Class Rational is not multiple thread safe.
|
|
*
|
|
* @author Alan Kaminsky
|
|
* @version 01-Dec-2004
|
|
*/
|
|
public class Rational
|
|
implements Comparable, Serializable
|
|
{
|
|
|
|
// Hidden data members.
|
|
|
|
private int numer;
|
|
private int denom;
|
|
|
|
// Exported constructors.
|
|
|
|
/**
|
|
* Construct a new rational number. Its value is 0.
|
|
*/
|
|
public Rational()
|
|
{
|
|
numer = 0;
|
|
denom = 1;
|
|
}
|
|
|
|
/**
|
|
* Construct a new rational number. Its value is <TT>value</TT>.
|
|
*
|
|
* @param value Value.
|
|
*/
|
|
public Rational
|
|
(int value)
|
|
{
|
|
numer = value;
|
|
denom = 1;
|
|
}
|
|
|
|
/**
|
|
* Construct a new rational number. Its value is <TT>numer/denom</TT>.
|
|
*
|
|
* @param numer Numerator.
|
|
* @param denom Denominator.
|
|
*
|
|
* @exception ArithmeticException
|
|
* (unchecked exception) Thrown if <TT>denom</TT> is 0.
|
|
*/
|
|
public Rational
|
|
(int numer,
|
|
int denom)
|
|
{
|
|
if (denom == 0)
|
|
{
|
|
throw new ArithmeticException ("Divide by zero");
|
|
}
|
|
this.numer = numer;
|
|
this.denom = denom;
|
|
normalize();
|
|
}
|
|
|
|
/**
|
|
* Construct a new rational number. Its value is <TT>value</TT>.
|
|
*
|
|
* @param value Rational number.
|
|
*/
|
|
public Rational
|
|
(Rational value)
|
|
{
|
|
this.numer = value.numer;
|
|
this.denom = value.denom;
|
|
}
|
|
|
|
/**
|
|
* Construct a new rational number. Its value comes from the string
|
|
* <TT>s</TT>. The string must obey this syntax: optional minus sign
|
|
* (<TT>-</TT>), numerator (decimal integer), slash (<TT>/</TT>),
|
|
* denominator (decimal integer). The slash-and-denominator is optional. If
|
|
* present, the denominator must be greater than 0. There is no whitespace
|
|
* within the string.
|
|
*
|
|
* @param s String.
|
|
*
|
|
* @exception NumberFormatException
|
|
* (unchecked exception) Thrown if <TT>s</TT> cannot be parsed into a
|
|
* rational number.
|
|
*/
|
|
public Rational
|
|
(String s)
|
|
{
|
|
assign (s);
|
|
}
|
|
|
|
// Exported operations.
|
|
|
|
/**
|
|
* Set this rational number to the given number.
|
|
*
|
|
* @param x Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x</TT>.
|
|
*/
|
|
public Rational assign
|
|
(Rational x)
|
|
{
|
|
this.numer = x.numer;
|
|
this.denom = x.denom;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the given number.
|
|
*
|
|
* @param x Integer.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x</TT>.
|
|
*/
|
|
public Rational assign
|
|
(int x)
|
|
{
|
|
this.numer = x;
|
|
this.denom = 1;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the value parsed from the given string. The
|
|
* string must obey this syntax: optional minus sign (<TT>-</TT>), numerator
|
|
* (decimal integer), slash (<TT>/</TT>), denominator (decimal integer). The
|
|
* slash-and-denominator is optional. If present, the denominator must be
|
|
* greater than 0. There is no whitespace within the string.
|
|
*
|
|
* @param s String.
|
|
*
|
|
* @return This rational number, with its value set to <TT>s</TT>.
|
|
*
|
|
* @exception NumberFormatException
|
|
* (unchecked exception) Thrown if <TT>s</TT> cannot be parsed into a
|
|
* rational number.
|
|
*/
|
|
public Rational assign
|
|
(String s)
|
|
{
|
|
int numer, denom;
|
|
int iSlash = s.indexOf ('/');
|
|
if (iSlash == -1)
|
|
{
|
|
// No denominator.
|
|
numer = Integer.parseInt (s);
|
|
denom = 1;
|
|
}
|
|
else if (iSlash+1 < s.length())
|
|
{
|
|
// Slash and denominator.
|
|
numer = Integer.parseInt (s.substring (0, iSlash));
|
|
denom = Integer.parseInt (s.substring (iSlash+1));
|
|
if (denom <= 0)
|
|
{
|
|
throw new NumberFormatException();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Slash but no denominator.
|
|
throw new NumberFormatException();
|
|
}
|
|
this.numer = numer;
|
|
this.denom = denom;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the negative of the given number.
|
|
*
|
|
* @param x Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>-x</TT>.
|
|
*/
|
|
public Rational neg
|
|
(Rational x)
|
|
{
|
|
this.numer = -x.numer;
|
|
this.denom = x.denom;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the negative of the given number.
|
|
*
|
|
* @param x Integer.
|
|
*
|
|
* @return This rational number, with its value set to <TT>-x</TT>.
|
|
*/
|
|
public Rational neg
|
|
(int x)
|
|
{
|
|
this.numer = -x;
|
|
this.denom = 1;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the absolute value of the given number.
|
|
*
|
|
* @param x Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>abs(x)</TT>.
|
|
*/
|
|
public Rational abs
|
|
(Rational x)
|
|
{
|
|
this.numer = absval (x.numer);
|
|
this.denom = x.denom;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the absolute value of the given number.
|
|
*
|
|
* @param x Integer.
|
|
*
|
|
* @return This rational number, with its value set to <TT>abs(x)</TT>.
|
|
*/
|
|
public Rational abs
|
|
(int x)
|
|
{
|
|
this.numer = absval (x);
|
|
this.denom = 1;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the integer part of the given rational
|
|
* number.
|
|
*
|
|
* @param x Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>int(x)</TT>.
|
|
*/
|
|
public Rational intPart
|
|
(Rational x)
|
|
{
|
|
this.numer = x.numer / x.denom;
|
|
this.denom = 1;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the fractional part of the given rational
|
|
* number.
|
|
*
|
|
* @param x Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>frac(x)</TT>.
|
|
*/
|
|
public Rational fracPart
|
|
(Rational x)
|
|
{
|
|
this.numer = x.numer % x.denom;
|
|
this.denom = x.denom;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the sum of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x+y</TT>.
|
|
*/
|
|
public Rational add
|
|
(Rational x,
|
|
Rational y)
|
|
{
|
|
int lcm = leastCommonMultiple (x.denom, y.denom);
|
|
this.numer = (lcm / x.denom) * x.numer + (lcm / y.denom) * y.numer;
|
|
this.denom = lcm;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the sum of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x+y</TT>.
|
|
*/
|
|
public Rational add
|
|
(Rational x,
|
|
int y)
|
|
{
|
|
this.numer = x.numer + y * x.denom;
|
|
this.denom = x.denom;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the sum of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x+y</TT>.
|
|
*/
|
|
public Rational add
|
|
(int x,
|
|
Rational y)
|
|
{
|
|
this.numer = x * y.denom + y.numer;
|
|
this.denom = y.denom;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the sum of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x+y</TT>.
|
|
*/
|
|
public Rational add
|
|
(int x,
|
|
int y)
|
|
{
|
|
this.numer = x + y;
|
|
this.denom = 1;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the difference of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x-y</TT>.
|
|
*/
|
|
public Rational sub
|
|
(Rational x,
|
|
Rational y)
|
|
{
|
|
int lcm = leastCommonMultiple (x.denom, y.denom);
|
|
this.numer = (lcm / x.denom) * x.numer - (lcm / y.denom) * y.numer;
|
|
this.denom = lcm;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the difference of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x-y</TT>.
|
|
*/
|
|
public Rational sub
|
|
(Rational x,
|
|
int y)
|
|
{
|
|
this.numer = x.numer - y * x.denom;
|
|
this.denom = x.denom;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the difference of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x-y</TT>.
|
|
*/
|
|
public Rational sub
|
|
(int x,
|
|
Rational y)
|
|
{
|
|
this.numer = x * y.denom - y.numer;
|
|
this.denom = y.denom;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the difference of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x-y</TT>.
|
|
*/
|
|
public Rational sub
|
|
(int x,
|
|
int y)
|
|
{
|
|
this.numer = x - y;
|
|
this.denom = 1;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the product of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x*y</TT>.
|
|
*/
|
|
public Rational mul
|
|
(Rational x,
|
|
Rational y)
|
|
{
|
|
this.numer = x.numer * y.numer;
|
|
this.denom = x.denom * y.denom;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the product of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x*y</TT>.
|
|
*/
|
|
public Rational mul
|
|
(Rational x,
|
|
int y)
|
|
{
|
|
this.numer = x.numer * y;
|
|
this.denom = x.denom;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the product of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x*y</TT>.
|
|
*/
|
|
public Rational mul
|
|
(int x,
|
|
Rational y)
|
|
{
|
|
this.numer = x * y.numer;
|
|
this.denom = y.denom;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the product of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x*y</TT>.
|
|
*/
|
|
public Rational mul
|
|
(int x,
|
|
int y)
|
|
{
|
|
this.numer = x * y;
|
|
this.denom = 1;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the quotient of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x/y</TT>.
|
|
*
|
|
* @exception ArithmeticException
|
|
* (unchecked exception) Thrown if <TT>y</TT> is 0.
|
|
*/
|
|
public Rational div
|
|
(Rational x,
|
|
Rational y)
|
|
{
|
|
if (y.numer == 0)
|
|
{
|
|
throw new ArithmeticException ("Divide by zero");
|
|
}
|
|
int numer = x.numer * y.denom;
|
|
int denom = x.denom * y.numer;
|
|
this.numer = numer;
|
|
this.denom = denom;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the quotient of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x/y</TT>.
|
|
*
|
|
* @exception ArithmeticException
|
|
* (unchecked exception) Thrown if <TT>y</TT> is 0.
|
|
*/
|
|
public Rational div
|
|
(Rational x,
|
|
int y)
|
|
{
|
|
if (y == 0)
|
|
{
|
|
throw new ArithmeticException ("Divide by zero");
|
|
}
|
|
this.numer = x.numer;
|
|
this.denom = x.denom * y;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the quotient of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x/y</TT>.
|
|
*
|
|
* @exception ArithmeticException
|
|
* (unchecked exception) Thrown if <TT>y</TT> is 0.
|
|
*/
|
|
public Rational div
|
|
(int x,
|
|
Rational y)
|
|
{
|
|
if (y.numer == 0)
|
|
{
|
|
throw new ArithmeticException ("Divide by zero");
|
|
}
|
|
int numer = x * y.denom;
|
|
int denom = y.numer;
|
|
this.numer = numer;
|
|
this.denom = denom;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the quotient of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to <TT>x/y</TT>.
|
|
*
|
|
* @exception ArithmeticException
|
|
* (unchecked exception) Thrown if <TT>y</TT> is 0.
|
|
*/
|
|
public Rational div
|
|
(int x,
|
|
int y)
|
|
{
|
|
if (y == 0)
|
|
{
|
|
throw new ArithmeticException ("Divide by zero");
|
|
}
|
|
this.numer = x;
|
|
this.denom = y;
|
|
normalize();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the minimum of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to the smaller of
|
|
* <TT>x</TT> and <TT>y</TT>.
|
|
*/
|
|
public Rational min
|
|
(Rational x,
|
|
Rational y)
|
|
{
|
|
if (x.lt (y))
|
|
{
|
|
this.assign (x);
|
|
}
|
|
else
|
|
{
|
|
this.assign (y);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the minimum of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to the smaller of
|
|
* <TT>x</TT> and <TT>y</TT>.
|
|
*/
|
|
public Rational min
|
|
(Rational x,
|
|
int y)
|
|
{
|
|
if (x.lt (y))
|
|
{
|
|
this.assign (x);
|
|
}
|
|
else
|
|
{
|
|
this.assign (y);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the minimum of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to the smaller of
|
|
* <TT>x</TT> and <TT>y</TT>.
|
|
*/
|
|
public Rational min
|
|
(int x,
|
|
Rational y)
|
|
{
|
|
if (y.gt (x))
|
|
{
|
|
this.assign (x);
|
|
}
|
|
else
|
|
{
|
|
this.assign (y);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the minimum of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to the smaller of
|
|
* <TT>x</TT> and <TT>y</TT>.
|
|
*/
|
|
public Rational min
|
|
(int x,
|
|
int y)
|
|
{
|
|
this.assign (Math.min (x, y));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the maximum of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to the larger of
|
|
* <TT>x</TT> and <TT>y</TT>.
|
|
*/
|
|
public Rational max
|
|
(Rational x,
|
|
Rational y)
|
|
{
|
|
if (x.gt (y))
|
|
{
|
|
this.assign (x);
|
|
}
|
|
else
|
|
{
|
|
this.assign (y);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the maximum of the given numbers.
|
|
*
|
|
* @param x Rational number.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to the larger of
|
|
* <TT>x</TT> and <TT>y</TT>.
|
|
*/
|
|
public Rational max
|
|
(Rational x,
|
|
int y)
|
|
{
|
|
if (x.gt (y))
|
|
{
|
|
this.assign (x);
|
|
}
|
|
else
|
|
{
|
|
this.assign (y);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the maximum of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Rational number.
|
|
*
|
|
* @return This rational number, with its value set to the larger of
|
|
* <TT>x</TT> and <TT>y</TT>.
|
|
*/
|
|
public Rational max
|
|
(int x,
|
|
Rational y)
|
|
{
|
|
if (y.lt (x))
|
|
{
|
|
this.assign (x);
|
|
}
|
|
else
|
|
{
|
|
this.assign (y);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set this rational number to the maximum of the given numbers.
|
|
*
|
|
* @param x Integer.
|
|
* @param y Integer.
|
|
*
|
|
* @return This rational number, with its value set to the larger of
|
|
* <TT>x</TT> and <TT>y</TT>.
|
|
*/
|
|
public Rational max
|
|
(int x,
|
|
int y)
|
|
{
|
|
this.assign (Math.max (x, y));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is equal to zero.
|
|
*
|
|
* @return True if this rational number is equal to 0, false otherwise.
|
|
*/
|
|
public boolean eqZero()
|
|
{
|
|
return this.numer == 0;
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is not equal to zero.
|
|
*
|
|
* @return True if this rational number is not equal to 0, false otherwise.
|
|
*/
|
|
public boolean neZero()
|
|
{
|
|
return this.numer != 0;
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is less than zero.
|
|
*
|
|
* @return True if this rational number is less than 0, false otherwise.
|
|
*/
|
|
public boolean ltZero()
|
|
{
|
|
return this.numer < 0;
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is less than or equal to zero.
|
|
*
|
|
* @return True if this rational number is less than or equal to 0, false
|
|
* otherwise.
|
|
*/
|
|
public boolean leZero()
|
|
{
|
|
return this.numer <= 0;
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is greater than zero.
|
|
*
|
|
* @return True if this rational number is greater than 0, false otherwise.
|
|
*/
|
|
public boolean gtZero()
|
|
{
|
|
return this.numer > 0;
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is greater than or equal to zero.
|
|
*
|
|
* @return True if this rational number is greater than or equal to 0,
|
|
* false otherwise.
|
|
*/
|
|
public boolean geZero()
|
|
{
|
|
return this.numer >= 0;
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is equal to the given number.
|
|
*
|
|
* @param x Rational number.
|
|
*
|
|
* @return True if this rational number is equal to <TT>x</TT>, false
|
|
* otherwise.
|
|
*/
|
|
public boolean eq
|
|
(Rational x)
|
|
{
|
|
return this.numer == x.numer && this.denom == x.denom;
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is equal to the given number.
|
|
*
|
|
* @param x Integer.
|
|
*
|
|
* @return True if this rational number is equal to <TT>x</TT>, false
|
|
* otherwise.
|
|
*/
|
|
public boolean eq
|
|
(int x)
|
|
{
|
|
return this.numer == x && this.denom == 1;
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is not equal to the given number.
|
|
*
|
|
* @param x Rational number.
|
|
*
|
|
* @return True if this rational number is not equal to <TT>x</TT>, false
|
|
* otherwise.
|
|
*/
|
|
public boolean ne
|
|
(Rational x)
|
|
{
|
|
return this.numer != x.numer || this.denom != x.denom;
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is not equal to the given number.
|
|
*
|
|
* @param x Integer.
|
|
*
|
|
* @return True if this rational number is not equal to <TT>x</TT>, false
|
|
* otherwise.
|
|
*/
|
|
public boolean ne
|
|
(int x)
|
|
{
|
|
return this.numer != x || this.denom != 1;
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is less than the given number.
|
|
*
|
|
* @param x Rational number.
|
|
*
|
|
* @return True if this rational number is less than <TT>x</TT>, false
|
|
* otherwise.
|
|
*/
|
|
public boolean lt
|
|
(Rational x)
|
|
{
|
|
return new Rational() .sub (this, x) .ltZero();
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is less than the given number.
|
|
*
|
|
* @param x Integer.
|
|
*
|
|
* @return True if this rational number is less than <TT>x</TT>, false
|
|
* otherwise.
|
|
*/
|
|
public boolean lt
|
|
(int x)
|
|
{
|
|
return new Rational() .sub (this, x) .ltZero();
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is less than or equal to the given
|
|
* number.
|
|
*
|
|
* @param x Rational number.
|
|
*
|
|
* @return True if this rational number is less than or equal to
|
|
* <TT>x</TT>, false otherwise.
|
|
*/
|
|
public boolean le
|
|
(Rational x)
|
|
{
|
|
return new Rational() .sub (this, x) .leZero();
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is less than or equal to the given
|
|
* number.
|
|
*
|
|
* @param x Integer.
|
|
*
|
|
* @return True if this rational number is less than or equal to
|
|
* <TT>x</TT>, false otherwise.
|
|
*/
|
|
public boolean le
|
|
(int x)
|
|
{
|
|
return new Rational() .sub (this, x) .leZero();
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is greater than the given number.
|
|
*
|
|
* @param x Rational number.
|
|
*
|
|
* @return True if this rational number is greater than <TT>x</TT>, false
|
|
* otherwise.
|
|
*/
|
|
public boolean gt
|
|
(Rational x)
|
|
{
|
|
return new Rational() .sub (this, x) .gtZero();
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is greater than the given number.
|
|
*
|
|
* @param x Integer.
|
|
*
|
|
* @return True if this rational number is greater than <TT>x</TT>, false
|
|
* otherwise.
|
|
*/
|
|
public boolean gt
|
|
(int x)
|
|
{
|
|
return new Rational() .sub (this, x) .gtZero();
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is greater than or equal to the given
|
|
* number.
|
|
*
|
|
* @param x Rational number.
|
|
*
|
|
* @return True if this rational number is greater than or equal to
|
|
* <TT>x</TT>, false otherwise.
|
|
*/
|
|
public boolean ge
|
|
(Rational x)
|
|
{
|
|
return new Rational() .sub (this, x) .geZero();
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is greater than or equal to the given
|
|
* number.
|
|
*
|
|
* @param x Integer.
|
|
*
|
|
* @return True if this rational number is greater than or equal to
|
|
* <TT>x</TT>, false otherwise.
|
|
*/
|
|
public boolean ge
|
|
(int x)
|
|
{
|
|
return new Rational() .sub (this, x) .geZero();
|
|
}
|
|
|
|
/**
|
|
* Converts this rational number to an integer. If this rational number is
|
|
* not an exact integer, any fractional part is truncated.
|
|
*
|
|
* @return Integer value of this rational number.
|
|
*/
|
|
public int intValue()
|
|
{
|
|
return this.numer / this.denom;
|
|
}
|
|
|
|
/**
|
|
* Converts this rational number to a long integer. If this rational number
|
|
* is not an exact integer, any fractional part is truncated.
|
|
*
|
|
* @return Long integer value of this rational number.
|
|
*/
|
|
public long longValue()
|
|
{
|
|
return ((long) this.numer) / ((long) this.denom);
|
|
}
|
|
|
|
/**
|
|
* Converts this rational number to a single precision floating point
|
|
* number.
|
|
*
|
|
* @return Single precision floating point value of this rational number.
|
|
*/
|
|
public float floatValue()
|
|
{
|
|
return ((float) this.numer) / ((float) this.denom);
|
|
}
|
|
|
|
/**
|
|
* Converts this rational number to a double precision floating point
|
|
* number.
|
|
*
|
|
* @return Double precision floating point value of this rational number.
|
|
*/
|
|
public double doubleValue()
|
|
{
|
|
return ((double) this.numer) / ((double) this.denom);
|
|
}
|
|
|
|
/**
|
|
* Returns a string version of this rational number. If this rational number
|
|
* is an exact integer, the string is in the form <TT>"<numer>"</TT>,
|
|
* otherwise the string is in the form
|
|
* <TT>"<numer>/<denom>"</TT>. If this rational number is less
|
|
* than 0, the string begins with a minus sign (<TT>-</TT>).
|
|
*/
|
|
public String toString()
|
|
{
|
|
if (this.denom == 1)
|
|
{
|
|
return Integer.toString (this.numer);
|
|
}
|
|
else
|
|
{
|
|
return this.numer + "/" + this.denom;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Determine if this rational number is equal to the given object. To be
|
|
* equal, <TT>obj</TT> must be a non-null instance of class Rational whose
|
|
* value is the same as this rational number's value.
|
|
*
|
|
* @param obj Object to test.
|
|
*
|
|
* @return True if this rational number is equal to <TT>obj</TT>, false
|
|
* otherwise.
|
|
*/
|
|
public boolean equals
|
|
(Object obj)
|
|
{
|
|
return
|
|
obj instanceof Rational &&
|
|
eq ((Rational) obj);
|
|
}
|
|
|
|
/**
|
|
* Returns a hash code for this rational number.
|
|
*/
|
|
public int hashCode()
|
|
{
|
|
return this.numer + this.denom;
|
|
}
|
|
|
|
/**
|
|
* Compare this rational number to the given object.
|
|
*
|
|
* @param obj Object to compare to.
|
|
*
|
|
* @return A number less than, equal to, or greater than 0 if this rational
|
|
* number is less than, equal to, or greater than <TT>obj</TT>,
|
|
* respectively.
|
|
*
|
|
* @exception NullPointerException
|
|
* (unchecked exception) Thrown if <TT>obj</TT> is null.
|
|
* @exception ClassCastException
|
|
* (unchecked exception) Thrown if <TT>obj</TT> is not an instance of
|
|
* class Rational.
|
|
*/
|
|
public int compareTo
|
|
(Object obj)
|
|
{
|
|
return new Rational() .sub (this, (Rational) obj) .numer;
|
|
}
|
|
|
|
// Hidden operations.
|
|
|
|
/**
|
|
* Normalize this rational number. Afterwards, the denominator is greater
|
|
* than 0, and the denominator does not divide the numerator.
|
|
*/
|
|
private void normalize()
|
|
{
|
|
int sign = signum (numer) * signum (denom);
|
|
numer = absval (numer);
|
|
denom = absval (denom);
|
|
int gcd = greatestCommonDivisor (numer, denom);
|
|
numer = sign * numer / gcd;
|
|
denom = denom / gcd;
|
|
}
|
|
|
|
/**
|
|
* Returns the signum of the given number.
|
|
*/
|
|
private static int signum
|
|
(int x)
|
|
{
|
|
return x < 0 ? -1 : 1;
|
|
}
|
|
|
|
/**
|
|
* Returns the absolute value of the given number.
|
|
*/
|
|
private static int absval
|
|
(int x)
|
|
{
|
|
return x < 0 ? -x : x;
|
|
}
|
|
|
|
/**
|
|
* Returns the greatest common divisor of the given numbers. <TT>x</TT> and
|
|
* <TT>y</TT> are assumed to be greater than 0.
|
|
*/
|
|
private static int greatestCommonDivisor
|
|
(int x,
|
|
int y)
|
|
{
|
|
int r;
|
|
while (y != 0)
|
|
{
|
|
r = x % y;
|
|
x = y;
|
|
y = r;
|
|
}
|
|
return x;
|
|
}
|
|
|
|
/**
|
|
* Returns the least common multiple of the given numbers. <TT>x</TT> and
|
|
* <TT>y</TT> are assumed to be greater than 0.
|
|
*/
|
|
private static int leastCommonMultiple
|
|
(int x,
|
|
int y)
|
|
{
|
|
return (x / greatestCommonDivisor (x, y)) * y;
|
|
}
|
|
|
|
}
|