diff options
author | Linnea Gräf <roman.graef@gmail.com> | 2023-10-18 16:12:19 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-18 16:12:19 +0200 |
commit | e0a2f5f5991048317f5c045feca084a1413c45fd (patch) | |
tree | 7e4e8795aa98e58d6df467598b82c1c53997c869 /src/main/java | |
parent | 5ad2c41fb936fbb9927aa0b73c73f93f9fd1c3a0 (diff) | |
download | NotEnoughUpdates-e0a2f5f5991048317f5c045feca084a1413c45fd.tar.gz NotEnoughUpdates-e0a2f5f5991048317f5c045feca084a1413c45fd.tar.bz2 NotEnoughUpdates-e0a2f5f5991048317f5c045feca084a1413c45fd.zip |
Add calculator precision option (#882)
* Add calculator precision option
* Fix loading of minecraft classes from some tests
Diffstat (limited to 'src/main/java')
3 files changed, 56 insertions, 17 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/NeuSearchCalculator.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/NeuSearchCalculator.java index 71dedb12..66b6d2d5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/NeuSearchCalculator.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/NeuSearchCalculator.java @@ -48,7 +48,7 @@ public class NeuSearchCalculator { lastInput = input; try { BigDecimal calculate = Calculator.calculate(input, PROVIDE_LOWEST_BIN); - lastResult = new DecimalFormat("#,##0.##").format(calculate); + lastResult = Calculator.getDecimalFormat().format(calculate); } catch (Calculator.CalculatorException ignored) { lastResult = null; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/Misc.java b/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/Misc.java index 72521821..a9a0856e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/Misc.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/Misc.java @@ -259,6 +259,18 @@ public class Misc { @Expose @ConfigOption( + name = "Calculator Precision", + desc = "Digits after the , to display in the calculator" + ) + @ConfigEditorSlider( + minValue = 1, + maxValue = 100, + minStep = 1 + ) + public int calculationPrecision = 5; + + @Expose + @ConfigOption( name = "Enable Abiphone Warning", desc = "Asks for confirmation when removing a contact in the abiphone" ) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java index 2b741e94..6b6d0074 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java @@ -19,8 +19,11 @@ package io.github.moulberry.notenoughupdates.util; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; + import java.math.BigDecimal; import java.math.RoundingMode; +import java.text.DecimalFormat; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; @@ -34,6 +37,14 @@ public class Calculator { Optional<BigDecimal> provideVariable(String name) throws CalculatorException; } + public static DecimalFormat getDecimalFormat() { + StringBuilder f = new StringBuilder("#,##0."); + for (int i = 0; i < NotEnoughUpdates.INSTANCE.config.misc.calculationPrecision; i++) { + f.append("#"); + } + return new DecimalFormat(f.toString()); + } + public static BigDecimal calculate(String source, VariableProvider variables) throws CalculatorException { return evaluate(variables, shuntingYard(lex(source))); } @@ -269,6 +280,7 @@ public class Calculator { ///<editor-fold desc="Evaluating Time"> public static BigDecimal evaluate(VariableProvider provider, List<Token> rpnTokens) throws CalculatorException { Deque<BigDecimal> values = new ArrayDeque<>(); + int precision = NotEnoughUpdates.INSTANCE != null ? NotEnoughUpdates.INSTANCE.config.misc.calculationPrecision : 5; try { for (Token command : rpnTokens) { switch (command.type) { @@ -287,42 +299,54 @@ public class Calculator { values.push(new BigDecimal(command.numericValue).scaleByPowerOfTen(command.exponent)); break; case BINOP: - BigDecimal right = values.pop().setScale(2, RoundingMode.HALF_UP); - BigDecimal left = values.pop().setScale(2, RoundingMode.HALF_UP); + BigDecimal right = values.pop().setScale(precision, RoundingMode.HALF_UP); + BigDecimal left = values.pop().setScale(precision, RoundingMode.HALF_UP); switch (command.operatorValue.intern()) { case "^": if (right.compareTo(new BigDecimal(1000)) >= 0) { Token rightToken = rpnTokens.get(rpnTokens.indexOf(command) - 1); - throw new CalculatorException(right + " is too large, pick a power less than 1000", rightToken.tokenStart, rightToken.tokenLength); + throw new CalculatorException( + right + " is too large, pick a power less than 1000", + rightToken.tokenStart, + rightToken.tokenLength + ); } if (right.doubleValue() != right.intValue()) { Token rightToken = rpnTokens.get(rpnTokens.indexOf(command) - 1); - throw new CalculatorException(right + " has a decimal, pick a power that is non-decimal", rightToken.tokenStart, rightToken.tokenLength); + throw new CalculatorException( + right + " has a decimal, pick a power that is non-decimal", + rightToken.tokenStart, + rightToken.tokenLength + ); } if (right.doubleValue() < 0) { Token rightToken = rpnTokens.get(rpnTokens.indexOf(command) - 1); - throw new CalculatorException(right + " is a negative number, pick a power that is positive", rightToken.tokenStart, rightToken.tokenLength); + throw new CalculatorException( + right + " is a negative number, pick a power that is positive", + rightToken.tokenStart, + rightToken.tokenLength + ); } - values.push(left.pow(right.intValue()).setScale(2, RoundingMode.HALF_UP)); + values.push(left.pow(right.intValue()).setScale(precision, RoundingMode.HALF_UP)); break; case "x": case "*": - values.push(left.multiply(right).setScale(2, RoundingMode.HALF_UP)); + values.push(left.multiply(right).setScale(precision, RoundingMode.HALF_UP)); break; case "/": try { - values.push(left.divide(right, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP)); + values.push(left.divide(right, RoundingMode.HALF_UP).setScale(precision, RoundingMode.HALF_UP)); } catch (ArithmeticException e) { throw new CalculatorException("Encountered division by 0", command.tokenStart, command.tokenLength); } break; case "+": - values.push(left.add(right).setScale(2, RoundingMode.HALF_UP)); + values.push(left.add(right).setScale(precision, RoundingMode.HALF_UP)); break; case "-": - values.push(left.subtract(right).setScale(2, RoundingMode.HALF_UP)); + values.push(left.subtract(right).setScale(precision, RoundingMode.HALF_UP)); break; default: throw new CalculatorException( @@ -343,22 +367,25 @@ public class Calculator { BigDecimal p = values.pop(); switch (command.operatorValue.intern()) { case "s": - values.push(p.multiply(new BigDecimal(64)).setScale(2, RoundingMode.HALF_UP)); + values.push(p.multiply(new BigDecimal(64)).setScale(precision, RoundingMode.HALF_UP)); break; case "k": - values.push(p.multiply(new BigDecimal(1_000)).setScale(2, RoundingMode.HALF_UP)); + values.push(p.multiply(new BigDecimal(1_000)).setScale(precision, RoundingMode.HALF_UP)); break; case "m": - values.push(p.multiply(new BigDecimal(1_000_000)).setScale(2, RoundingMode.HALF_UP)); + values.push(p.multiply(new BigDecimal(1_000_000)).setScale(precision, RoundingMode.HALF_UP)); break; case "b": - values.push(p.multiply(new BigDecimal(1_000_000_000)).setScale(2, RoundingMode.HALF_UP)); + values.push(p.multiply(new BigDecimal(1_000_000_000)).setScale(precision, RoundingMode.HALF_UP)); break; case "t": - values.push(p.multiply(new BigDecimal("1000000000000")).setScale(2, RoundingMode.HALF_UP)); + values.push(p.multiply(new BigDecimal("1000000000000")).setScale(precision, RoundingMode.HALF_UP)); break; case "%": - values.push(p.setScale(3, RoundingMode.HALF_UP).divide(new BigDecimal(100), RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP)); + values.push(p + .setScale(precision + 1, RoundingMode.HALF_UP) + .divide(new BigDecimal(100), RoundingMode.HALF_UP) + .setScale(precision, RoundingMode.HALF_UP)); break; default: throw new CalculatorException( |