patternjavaMinor
I made a BigFraction class in Java. It's a bit slow
Viewed 0 times
bitmadebigfractionjavaslowclass
Problem
Thanks for looking it over. I'm still pretty new to programming. I thought this would be a good exercise in addition to making the Project Euler fraction problems easier
```
import java.math.BigInteger;
final class BigFraction extends Number{
private BigInteger numerator;
private BigInteger denominator;
public final static BigFraction ZERO = new BigFraction(BigInteger.ZERO);
public BigFraction(String numerator, String denominator, boolean reduce){
this(new BigInteger(numerator), new BigInteger(denominator));
if(reduce)
this.reduce();
}
public BigFraction(long numerator, long denominator){
this(BigInteger.valueOf(numerator), BigInteger.valueOf(denominator));
}
public BigFraction(String numerator, String denominator){
this(new BigInteger(numerator), new BigInteger(denominator));
}
public BigFraction(BigInteger numerator, BigInteger denominator){
if(denominator.signum() == 0)
throw new IllegalArgumentException("Denominator can't be zero");
if(numerator.signum() == 0){
denominator = BigInteger.ONE;
}
if(denominator.signum() == -1){
numerator = numerator.multiply( BigInteger.valueOf(-1 ));
denominator = denominator.multiply( BigInteger.valueOf(-1 ));
}
this.numerator = numerator;
this.denominator= denominator;
}
public void reduce(){
if( ! this.numerator.equals(BigInteger.ZERO) ){
BigInteger GCF = (GCF(this.numerator, this.denominator)).abs();
this.numerator = this.numerator.divide(GCF);
this.denominator = this.denominator.divide(GCF);
}
}
public BigFraction(BigInteger numerator){
this.numerator = numerator;
this.denominator = BigInteger.ONE;
}
public static BigFraction valueOf(long numerator, long denominator){
return new BigFraction(BigInteger.valueOf(numerator), BigInteger.value
```
import java.math.BigInteger;
final class BigFraction extends Number{
private BigInteger numerator;
private BigInteger denominator;
public final static BigFraction ZERO = new BigFraction(BigInteger.ZERO);
public BigFraction(String numerator, String denominator, boolean reduce){
this(new BigInteger(numerator), new BigInteger(denominator));
if(reduce)
this.reduce();
}
public BigFraction(long numerator, long denominator){
this(BigInteger.valueOf(numerator), BigInteger.valueOf(denominator));
}
public BigFraction(String numerator, String denominator){
this(new BigInteger(numerator), new BigInteger(denominator));
}
public BigFraction(BigInteger numerator, BigInteger denominator){
if(denominator.signum() == 0)
throw new IllegalArgumentException("Denominator can't be zero");
if(numerator.signum() == 0){
denominator = BigInteger.ONE;
}
if(denominator.signum() == -1){
numerator = numerator.multiply( BigInteger.valueOf(-1 ));
denominator = denominator.multiply( BigInteger.valueOf(-1 ));
}
this.numerator = numerator;
this.denominator= denominator;
}
public void reduce(){
if( ! this.numerator.equals(BigInteger.ZERO) ){
BigInteger GCF = (GCF(this.numerator, this.denominator)).abs();
this.numerator = this.numerator.divide(GCF);
this.denominator = this.denominator.divide(GCF);
}
}
public BigFraction(BigInteger numerator){
this.numerator = numerator;
this.denominator = BigInteger.ONE;
}
public static BigFraction valueOf(long numerator, long denominator){
return new BigFraction(BigInteger.valueOf(numerator), BigInteger.value
Solution
You should use
I think for multiplication
There is a BigFraction class in Apache Commons, maybe you can get some inspiration there...
BTW, method and variable names should be lower-case.
[Update]
I think you should always reduce fractions. This allows you to use shortcuts (e.g. in
I'm not sure this is faster, but it's worth a try.
Concerning lower-case variable and method names I thought about things like
BigInteger.gcd() instead of GCF(), also in isReduced(). Don't use compareTo in equals: If your fractions are always in reduced form, you can just compare numerators and denominators. In compareTo, you could test some special cases to avoid multiplication, e.g. a/b > c/d if a > c and b 0).I think for multiplication
a/b * c/d, it could be faster to reduce a and d, as well as b and c, instead of doing the reduction after the multiplication.There is a BigFraction class in Apache Commons, maybe you can get some inspiration there...
BTW, method and variable names should be lower-case.
[Update]
I think you should always reduce fractions. This allows you to use shortcuts (e.g. in
equals and compareTo), and also faster calculations. If fractions are always reduced, you can compare numerators and denominators in equals (instead of calling compareTo). Further, for multiplication you can reduce before you multiply:public BigFraction multiply(BigFraction frac){
BigInteger gcd1 = this.getNumerator().gcd(frac.getDenominator());
BigInteger num1 = this.getNumerator().divide(gcd1);
BigInteger den1 = frac.getDenominator().divide(gcd1);
BigInteger gcd2 = frac.getNumerator().gcd(this.getDenominator());
BigInteger num2 = frac.getNumerator().divide(gcd2);
BigInteger den2 = this.getDenominator().divide(gcd2);
BigInteger newNumerator = num1.multiply(num2);
BigInteger newDenominator = den1.multiply(den2);
return new BigFraction(newNumerator, newDenominator); //already reduced
}I'm not sure this is faster, but it's worth a try.
Concerning lower-case variable and method names I thought about things like
BigInteger LCM = LCM(frac);.Code Snippets
public BigFraction multiply(BigFraction frac){
BigInteger gcd1 = this.getNumerator().gcd(frac.getDenominator());
BigInteger num1 = this.getNumerator().divide(gcd1);
BigInteger den1 = frac.getDenominator().divide(gcd1);
BigInteger gcd2 = frac.getNumerator().gcd(this.getDenominator());
BigInteger num2 = frac.getNumerator().divide(gcd2);
BigInteger den2 = this.getDenominator().divide(gcd2);
BigInteger newNumerator = num1.multiply(num2);
BigInteger newDenominator = den1.multiply(den2);
return new BigFraction(newNumerator, newDenominator); //already reduced
}Context
StackExchange Code Review Q#25160, answer score: 3
Revisions (0)
No revisions yet.