diff --git a/src/org/nwapw/abacus/number/NaiveNumber.java b/src/org/nwapw/abacus/number/NaiveNumber.java index b201a91..b286196 100755 --- a/src/org/nwapw/abacus/number/NaiveNumber.java +++ b/src/org/nwapw/abacus/number/NaiveNumber.java @@ -88,6 +88,9 @@ public class NaiveNumber implements NumberInterface { @Override public NumberInterface promoteTo(Class toClass) { if(toClass == this.getClass()) return this; + else if(toClass == PreciseNumber.class){ + return new PreciseNumber(Double.toString(value)); + } return null; } diff --git a/src/org/nwapw/abacus/number/PreciseNumber.java b/src/org/nwapw/abacus/number/PreciseNumber.java new file mode 100755 index 0000000..3ea5cbc --- /dev/null +++ b/src/org/nwapw/abacus/number/PreciseNumber.java @@ -0,0 +1,112 @@ +package org.nwapw.abacus.number; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.MathContext; +import java.math.RoundingMode; + +public class PreciseNumber implements NumberInterface{ + + /** + * The number one. + */ + static final PreciseNumber ONE = new PreciseNumber(BigDecimal.ONE); + /** + * The number zero. + */ + static final PreciseNumber ZERO = new PreciseNumber(BigDecimal.ZERO); + /** + * The number ten. + */ + static final PreciseNumber TEN = new PreciseNumber(BigDecimal.TEN); + + BigDecimal value = new BigDecimal("0"); + + /** + * Constructs a precise number from the given string. + * @param string a string representation of the number meeting the same conditions + * as the BidDecimal(String) constructor. + */ + public PreciseNumber(String string){ + value = new BigDecimal(string); + } + + /** + * Constructs a precise number from the given BigDecimal. + * @param value a BigDecimal object representing the value of the number. + */ + public PreciseNumber(BigDecimal value){ + this.value = value; + } + + @Override + public int precision() { + return 54; + } + + @Override + public NumberInterface multiply(NumberInterface multiplier) { + return new PreciseNumber(value.multiply(((PreciseNumber) multiplier).value)); + } + + @Override + public NumberInterface divide(NumberInterface divisor) { + return new PreciseNumber(value.divide(((PreciseNumber) divisor).value, this.precision(), RoundingMode.HALF_UP)); + } + + @Override + public NumberInterface add(NumberInterface summand) { + return new PreciseNumber(value.add(((PreciseNumber) summand).value)); + } + + @Override + public NumberInterface subtract(NumberInterface subtrahend) { + return new PreciseNumber(value.subtract(((PreciseNumber) subtrahend).value)); + } + + @Override + public NumberInterface intPow(int exponent) { + if(exponent == 0){ + return PreciseNumber.ONE; + } + boolean takeReciprocal = exponent < 0; + exponent = Math.abs(exponent); + NumberInterface power = this; + for(int currentExponent = 1; currentExponent < exponent; currentExponent++){ + power = power.multiply(this); + } + if(takeReciprocal){ + power = PreciseNumber.ONE.divide(power); + } + return power; + } + + @Override + public int compareTo(NumberInterface number) { + return value.compareTo(((PreciseNumber) number).value); + } + + @Override + public int signum() { + return value.signum(); + } + + @Override + public NumberInterface negate(){ + return new PreciseNumber(value.negate()); + } + + @Override + public NumberInterface promoteTo(Class toClass) { + if(toClass == this.getClass()){ + return this; + } + return null; + } + + @Override + public String toString() { + BigDecimal rounded = value.setScale(precision() - 4, RoundingMode.HALF_UP); + return rounded.stripTrailingZeros().toPlainString(); + } +} diff --git a/src/org/nwapw/abacus/plugin/StandardPlugin.java b/src/org/nwapw/abacus/plugin/StandardPlugin.java index 01b988e..68232d3 100755 --- a/src/org/nwapw/abacus/plugin/StandardPlugin.java +++ b/src/org/nwapw/abacus/plugin/StandardPlugin.java @@ -228,7 +228,7 @@ public class StandardPlugin extends Plugin { @Override protected NumberInterface applyInternal(NumberInterface[] params) { - return StandardPlugin.this.getOperator("^").getFunction().apply(params[0], (new NaiveNumber(0.5))); + return StandardPlugin.this.getOperator("^").getFunction().apply(params[0], ((new NaiveNumber(0.5)).promoteTo(params[0].getClass()))); } }); }