```/**
* An immutable rational number.
*
* @author Drue Coles
*/
public class RationalNumber {

public static final RationalNumber ZERO = new RationalNumber(0);
public static final RationalNumber ONE = new RationalNumber(1);
public static final RationalNumber ONE_FOURTH = new RationalNumber(1, 4);
public static final RationalNumber ONE_THIRD = new RationalNumber(1, 3);
public static final RationalNumber ONE_HALF = new RationalNumber(1, 2);

private final int numerator;
private final int denominator;

/**
* Constructs a rational number with a specified numerator and denominator. If the
* denominator is zero, the constructor fails silently.
*
* @param numerator an arbitrary integer
* @param denominator a non-zero integer
*/
public RationalNumber(int numerator, int denominator) {

// The greatest common divisor of the numerator and denominator will be factored
// out so that each rational number has a unique representation.
int gcd = gcd(numerator, denominator);

// It is convenient to store the denominator as a positive integer, so if needed
// we can take the additive inverse of both numerator and denominator.
if (denominator < 0) {
this.numerator = -numerator / gcd;
this.denominator = -denominator / gcd;
} else {
this.numerator = numerator / gcd;
this.denominator = denominator / gcd;
}
}

/**
* Constructs an integer rational number (i.e., denominator is 1).
*/
public RationalNumber(int num) {
this.numerator = num;
this.denominator = 1;
}

/**
* Returns the multiplicative inverse of this object.
*/
public RationalNumber inverse() {
return new RationalNumber(denominator, numerator);
}

/**
* Returns the sum of this rational number and a given rational number.
*/
int n = this.numerator * other.denominator + other.numerator * this.denominator;
int d = this.denominator * other.denominator;
return new RationalNumber(n, d);
}

/**
* Returns the result of subtracting a given rational number from this rational
* number.
*/
public RationalNumber subtract(RationalNumber other) {
int n = this.numerator * other.denominator - other.numerator * this.denominator;
int d = this.denominator * other.denominator;
return new RationalNumber(n, d);
}

/**
* Returns the product of this rational number and a given rational number.
*/
public RationalNumber multiply(RationalNumber other) {
int n = this.numerator * other.numerator;
int d = this.denominator * other.denominator;
return new RationalNumber(n, d);
}

/**
* Returns the result of dividing this rational number by a given rational number.
*/
public RationalNumber divide(RationalNumber other) {
return multiply(other.inverse());
}

/**
* Returns the rational number as a string in the standard format.
*/
@Override
public String toString() {
if (denominator == 1) {
return "" + numerator;
}
if (numerator == 0) {
return "0";
}
return numerator + "/" + denominator;
}

/**
* Returns true if and only if this RationalNumber is numerically equal to obj.
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}

RationalNumber other = (RationalNumber) obj;

// We do not need to cross multiply, since all RationalNumbers are represented
// by a numerator and denominator in lowest terms.
return numerator == other.numerator && denominator == other.denominator;
}

/**
* Returns the hash code value for this RationalNumber.
*/
@Override
public int hashCode() {
int hash = 7;
hash = 89 * hash + this.numerator;
hash = 89 * hash + this.denominator;
return hash;
}

/**
* Returns the greatest common divisor of two integers.
*/
private int gcd(int x, int y) {
x = Math.abs(x);
y = Math.abs(y);

// Euclid's algorithm
int a = Math.max(x, y);
int b = Math.min(x, y);
while (b > 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
}
```