# Source code for Rational.java

What follows is the highlighted source code with comments. You can also download this file directly: Rational.java.

```/*
* This work by W. Patrick Hooper is free of known copyright restrictions.
* The work is in the public domain.
*
* Author's website: <a href="http://wphooper.com">http://wphooper.com</a>.
*/

package number;

// Allow us to use Java's built in BigInteger class
import java.math.BigInteger;

/**
* An instance of this class stores a rational number. The rational is
* normalized so that the denominator is always positive, and the
* numerator and denominator are relatively prime.
*
* @author W. Patrick Hooper (wphooper@gmail.com)
*/
public class Rational {

/** The numerator and denominator.
* I've marked these things private, because I don't want anyone accessing them directly.
* I've marked them final, because I don't want them to change once I've set them.
*/
private final BigInteger n, d;

/** Return the numerator of this rational. */
public BigInteger numerator() {
return n;
}

/** Return the denominator of this rational. */
public BigInteger denominator() {
return d;
}

/** Construct a rational with an integral value. */
public Rational(BigInteger numerator) {
n = numerator;
d = BigInteger.valueOf(1);
}

/** Construct a rational with an integral value. */
public Rational(long numerator) {
this(BigInteger.valueOf(numerator));
}

/** Construct the rational p/q. */
public Rational(BigInteger p, BigInteger q) {
// the signnum function returns 1 if q>0, 0 if q=0, and -1 if q<0.
int s = q.signum();

// So, this says "if d<0"...
if (s <= 0) {
// if s is 0, then we have a zero in the denominator!
if (s == 0) {
// this throws an exception to indicate that we divided by zero
// So, this rational is going to be invalid.
throw new ArithmeticException("Division by zero in fraction");
}

// Now we will negate both the numerator and denominator.
// This guarantees that we are storing the same rational, but
// now the denominator is positive.
p = p.negate();
q = q.negate();
}
// Set x to be the GCD of n and d.
BigInteger x = p.gcd(q);

// store the numerator divided by the GCD
n = p.divide(x);
// store the denominator divided by the GCD
d = q.divide(x);
}

/** Construct the rational p/q. */
public Rational(long p, long q) {
this(BigInteger.valueOf(p), BigInteger.valueOf(q));
}

/** Return the sign of this rational. It returns 1 if the rational is positive,
* 0 if the rational is zero, and -1 if the rational is negative.
*/
public int signum() {
return numerator().signum();
}

/** Convert this rational to a string. */
@Override
public String toString() {
if (this.denominator().equals(BigInteger.ONE)) {
// We have an integer, return just the numerator.
return this.numerator().toString();
} else {
// We have a non-trivial denominator, we'll return the ratio.
// Following a string by a "+" and an object converts the object to
// a string and concatenates the two strings.
return "" + this.numerator() + "/" + this.denominator();
}
}

/**
* Return true if the object is a rational which is numerically equal to
* this rational.
* @param obj The object to compare to.
*/
@Override
public boolean equals(Object obj) {
// Return false if the object is null
if (obj == null) return false;
// Return true if passed the exact same object
if (obj == this) return true;
// Return false if the object is not a rational
if (!(obj instanceof Rational)) return false;

// now the object must be a rational, so we can convert it to a rational
Rational other = (Rational) obj;

// if the numerators are not equal return false
if (! this.n.equals(other.n)) {
return false;
}
// if the denominators are not equal return false
if (! this.d.equals(other.d)) {
return false;
}
// The numerator and denominator are equal: return true
return true;
}

// Remark: In Java, we should really override the hashcode function
// whenever we override the equals function. But, I don't want to
// get into this for a light introduction to programming in java.

}
```
HOOPER >>>>> JAVA TUTORIAL