Implementation of a Fraction class in Java I am writing a bunch of Math related classes:BigInteger,Fraction,matrix,vector,polynomial,set etc.All of these classes will use each other.The classes will either work in decimal format or in Rational format at a time(eg as FractionalMatrix and DecimalMatrix) so I thought it will be best to implement the Fraction class first.

My primary concern is that this is going to be a big project.So, code readability and management is very important.Any suggestions on making the code better are appreciated.

Here is the Fraction class:

public final class Fraction {

private int numerator;

private int denominator;

public Fraction(int numerator,int denominator,boolean wantToReduce) {
    if (denominator == 0) {
        throw new IllegalArgumentException("The denominator is zero.");
    }
    if(numerator==0){
        this.numerator = 0;
        this.denominator = 1;
    }
    else{
    this.numerator = numerator;
    this.denominator = denominator;
    }
    if(denominator&lt;0){
        this.numerator = -1*this.numerator;
        this.denominator = -1*this.denominator;
    }
    if(wantToReduce==true)
        this.reduce();
}
public Fraction(int num) {
    this.numerator = num;
    this.denominator = 1;
}

@Override
public String toString() {
    if(denominator!=1)
    return numerator+"/"+denominator;
    else
        return numerator+"";
}

@Override
public boolean equals(Object obj) {
    if(!(obj instanceof Fraction))
        return false;
    Fraction f = ((Fraction)obj);
    int gcd= Math2.gcd(numerator,denominator);
    f.reduce();
    if(this.numerator/gcd==f.numerator &amp;&amp; this.denominator/gcd == f.denominator)
        return true;
    else
        return false;
}

public Fraction reduce(){
    int gcd = Math2.gcd(numerator,denominator);
    numerator = numerator/gcd;
    denominator = denominator/gcd;
    return this;
}

//Cannot decide weather to make static methods or not so I randomly picked one. 
public static Fraction add(Fraction f1,Fraction f2,boolean w){
    return new Fraction(f1.numerator*f2.denominator+f2.numerator*f1.denominator,f1.denominator*f2.denominator,w);
}
public static Fraction sub(Fraction f1,Fraction f2,boolean w){
    return new Fraction(f1.numerator*f2.denominator-f2.numerator*f1.denominator,f1.denominator*f2.denominator,w);
}
public static Fraction mul(Fraction f1,Fraction f2,boolean w){
    return new Fraction(f1.numerator*f2.numerator,f1.denominator*f2.denominator,w);
}
public static Fraction div(Fraction f1,Fraction f2,boolean w){
    return new Fraction(f1.numerator*f2.denominator,f1.denominator*f2.numerator,w);
}


}


Here is the Math2.gcd method, I have used The Euclidean Algorithm for finding the GCD.

 public static int gcd(int a,int b){
    if(a&lt;0)
        a=-1*a;
    if(b&lt;0)
        b=-1*b;
    int t;
    while(b!=0){
        t=b;
        b = a%b;
        a = t;          
    }
    return a;
}
I'm not going to repeat the basics which Ronan has covered fairly comprehensively. I'd just add: why use -1*a when you could use -a?

However, I have some design questions:

Reduction

I have a Rational class which I have used for about 15 years. It always reduces, and I've never found this to be a problem. Why would you want unreduced fractions?

In addition, consider that being reduced or not is not really an property of the number: it's a property of how the number is displayed in text. If you have use cases, would they be covered equally well or better by a toString method which takes a desired denominator?

Among the advantages of using reduced numbers are i) it simplifies equality testing; ii) it reduces the risk of overflow (or improves memory usage and speed, if using BigIntegers for numerator and denominator).

Mutability

Whether you keep unreduced numbers or not, make them immutable. In fact, I would recommend making every class in your CAS immutable, and using the builder pattern if you think this makes it too hard to instantiate matrices.

int vs BigInteger

Why are the numerator and denominator stored as ints? They will easily overflow, especially given that adding two rationals requires multiplying numerators and denominators. If you do stick with ints to keep memory usage low then you should cast to longs in the arithmetic methods and then reduce before casting back to ints, but I would recommend using BigInteger.

A final note

Well done for considering the special cases around zero and negative numbers in the constructor.