From 1d6957c4d94aebdb08942dd09168a5d8b62a2d79 Mon Sep 17 00:00:00 2001 From: Arthur Drobot Date: Tue, 8 Aug 2017 14:53:34 -0700 Subject: [PATCH] Write a RationalNumber class. --- build.gradle | 1 + .../nwapw/abacus/number/PreciseNumber.java | 10 ++ .../nwapw/abacus/number/RationalNumber.java | 115 ++++++++++++++++++ 3 files changed, 126 insertions(+) mode change 100644 => 100755 build.gradle create mode 100755 src/main/java/org/nwapw/abacus/number/RationalNumber.java diff --git a/build.gradle b/build.gradle old mode 100644 new mode 100755 index 1a408bc..cd5a65d --- a/build.gradle +++ b/build.gradle @@ -11,6 +11,7 @@ repositories { } dependencies { + compile group: 'org.apache.commons', name: 'commons-math3', version: '3.6.1' compile 'com.moandjiezana.toml:toml4j:0.7.1' compile "org.jetbrains.kotlin:kotlin-stdlib-jre8" testCompile 'junit:junit:4.12' diff --git a/src/main/java/org/nwapw/abacus/number/PreciseNumber.java b/src/main/java/org/nwapw/abacus/number/PreciseNumber.java index 094e5a9..2d515fc 100755 --- a/src/main/java/org/nwapw/abacus/number/PreciseNumber.java +++ b/src/main/java/org/nwapw/abacus/number/PreciseNumber.java @@ -1,6 +1,7 @@ package org.nwapw.abacus.number; import java.math.BigDecimal; +import java.math.BigInteger; import java.math.MathContext; /** @@ -61,6 +62,15 @@ public class PreciseNumber extends NumberInterface { this.value = value; } + /** + * Constructs a precise number from the given BigInteger. + * + * @param value a BigInteger object representing the value of the number. + */ + public PreciseNumber(BigInteger value) { + this.value = new BigDecimal(value); + } + @Override public int getMaxPrecision() { return internalContext.getPrecision(); diff --git a/src/main/java/org/nwapw/abacus/number/RationalNumber.java b/src/main/java/org/nwapw/abacus/number/RationalNumber.java new file mode 100755 index 0000000..62653e6 --- /dev/null +++ b/src/main/java/org/nwapw/abacus/number/RationalNumber.java @@ -0,0 +1,115 @@ +package org.nwapw.abacus.number; + +import org.apache.commons.math3.fraction.BigFraction; +import org.apache.commons.math3.fraction.Fraction; + +import java.math.BigInteger; + +public class RationalNumber extends NumberInterface{ + + static final RationalNumber ONE = new RationalNumber(BigFraction.ONE); + + /** + * The value of the number. + */ + private BigFraction value; + + /** + * Constructs a new instance with the given value. + * @param value + */ + public RationalNumber(BigFraction value){ + this.value = value; + } + + @Override + public int getMaxPrecision() { + return 0; + } + + @Override + protected NumberInterface multiplyInternal(NumberInterface multiplier) { + return new RationalNumber(value.multiply(((RationalNumber)multiplier).value)); + } + + @Override + protected NumberInterface divideInternal(NumberInterface divisor) { + return new RationalNumber(value.divide(((RationalNumber)divisor).value)); + } + + @Override + protected NumberInterface addInternal(NumberInterface summand) { + return new RationalNumber(value.add(((RationalNumber)summand).value)); + } + + @Override + protected NumberInterface subtractInternal(NumberInterface subtrahend) { + return new RationalNumber(value.subtract(((RationalNumber)subtrahend).value)); + } + + @Override + protected NumberInterface negateInternal() { + return new RationalNumber(value.negate()); + } + + @Override + protected NumberInterface intPowInternal(int exponent) { + return new RationalNumber(value.pow(exponent)); + } + + @Override + public int compareTo(NumberInterface number) { + return value.compareTo(((RationalNumber)number).value); + } + + @Override + public int signum() { + return value.getNumerator().signum(); + } + + @Override + protected NumberInterface ceilingInternal() { + if(value.getNumeratorAsInt() != 1){ + return floorInternal().add(ONE); + } + return this; + } + + @Override + protected NumberInterface floorInternal() { + BigInteger floor = value.bigDecimalValue().toBigInteger(); + if(value.compareTo(BigFraction.ZERO) < 0 && value.getDenominatorAsInt() != 1){ + floor = floor.subtract(BigInteger.ONE); + } + return new RationalNumber(new BigFraction(floor)); + } + + @Override + protected NumberInterface fractionalPartInternal() { + return this.subtractInternal(floorInternal()); + } + + @Override + public int intValue() { + return 0; + } + + @Override + protected NumberInterface promoteToInternal(Class toClass) { + return null; + } + + @Override + public NumberInterface getMaxError() { + return toPreciseNumber().getMaxError(); + } + + @Override + public String toString(){ + return toPreciseNumber().toString(); + } + + PreciseNumber toPreciseNumber(){ + return (PreciseNumber) new PreciseNumber(value.getNumerator()).divideInternal(new PreciseNumber(value.getDenominator())); + } +}