diff --git a/src/main/java/org/nwapw/abacus/fx/AbacusController.java b/src/main/java/org/nwapw/abacus/fx/AbacusController.java index d0cce54..06b10ac 100644 --- a/src/main/java/org/nwapw/abacus/fx/AbacusController.java +++ b/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -11,6 +11,7 @@ import javafx.util.Callback; import javafx.util.StringConverter; import org.nwapw.abacus.Abacus; import org.nwapw.abacus.config.Configuration; +import org.nwapw.abacus.number.ComputationInterruptedException; import org.nwapw.abacus.number.NumberInterface; import org.nwapw.abacus.plugin.ClassFinder; import org.nwapw.abacus.plugin.PluginListener; @@ -58,6 +59,10 @@ public class AbacusController implements PluginListener { * Constant string that is displayed if the calculations are stopped before they are done. */ private static final String ERR_STOP = "Stopped"; + /** + * Constant string that is displayed if the calculations are interrupted by an exception. + */ + private static final String ERR_EXCEPTION = "Exception Thrown"; @FXML private TabPane coreTabPane; @FXML @@ -79,6 +84,8 @@ public class AbacusController implements PluginListener { @FXML private Button inputButton; @FXML + private Button stopButton; + @FXML private ComboBox numberImplementationBox; @FXML private ListView enabledPluginView; @@ -95,7 +102,6 @@ public class AbacusController implements PluginListener { private ObservableList numberImplementationOptions; /** - * <<<<<<< HEAD * The list of plugin objects that can be toggled on and off, * and, when reloaded, get added to the plugin manager's black list. */ @@ -105,20 +111,6 @@ public class AbacusController implements PluginListener { * The abacus instance used for changing the plugin configuration. */ private Abacus abacus; - /** - * Thread used for calculating. - */ - private Thread calcThread; - - /** - * Checks whether the calculator is calculating. - */ - private boolean calculating; - - /** - * Seconds delayed for timer; - */ - private double delay = 0; /** * Boolean which represents whether changes were made to the configuration. @@ -132,6 +124,47 @@ public class AbacusController implements PluginListener { * The alert shown when a press to "apply" is needed. */ private Alert reloadAlert; + /** + * The runnable used to perform the calculation. + */ + private final Runnable CALCULATION_RUNNABLE = new Runnable() { + + private String attemptCalculation(){ + try { + TreeNode constructedTree = abacus.parseString(inputField.getText()); + if (constructedTree == null) { + return ERR_SYNTAX; + } + NumberInterface evaluatedNumber = abacus.evaluateTree(constructedTree); + if (evaluatedNumber == null) { + return ERR_EVAL; + } + String resultingString = evaluatedNumber.toString(); + historyData.add(new HistoryModel(inputField.getText(), constructedTree.toString(), resultingString)); + return resultingString; + } catch (ComputationInterruptedException exception) { + return ERR_STOP; + } catch (RuntimeException exception){ + exception.printStackTrace(); + return ERR_EXCEPTION; + } + } + + @Override + public void run() { + String calculation = attemptCalculation(); + Platform.runLater(() -> { + outputText.setText(calculation); + inputField.setText(""); + inputButton.setDisable(false); + stopButton.setDisable(true); + }); + } + }; + /** + * The thread in which the computation runs. + */ + private Thread calculationThread; /** * Alerts the user if the changes they made @@ -202,63 +235,16 @@ public class AbacusController implements PluginListener { @FXML private void performCalculation() { - Runnable calculator = new Runnable() { - public void run() { - if (delay > 0) { - Runnable timer = new Runnable() { - public void run() { - long gap = (long) (delay * 1000); - long startTime = System.currentTimeMillis(); - while (System.currentTimeMillis() - startTime <= gap) { - } - stopCalculation(); - } - }; - Thread maxTime = new Thread(timer); - maxTime.setName("maxTime"); - maxTime.start(); - } - calculating = true; - Platform.runLater(() -> inputButton.setDisable(true)); - TreeNode constructedTree = abacus.parseString(inputField.getText()); - if (constructedTree == null) { - Platform.runLater(() -> outputText.setText(ERR_SYNTAX)); - Platform.runLater(() -> inputButton.setDisable(false)); - //return; - } else { - NumberInterface evaluatedNumber = abacus.evaluateTree(constructedTree); - if (evaluatedNumber == null) { - if (Thread.currentThread().isInterrupted()) { - Platform.runLater(() -> outputText.setText(ERR_STOP)); - Platform.runLater(() -> inputButton.setDisable(false)); - } else { - Platform.runLater(() -> outputText.setText(ERR_EVAL)); - Platform.runLater(() -> inputButton.setDisable(false)); - //return; - } - } else { - Platform.runLater(() -> outputText.setText(evaluatedNumber.toString())); - historyData.add(new HistoryModel(inputField.getText(), constructedTree.toString(), evaluatedNumber.toString())); - - Platform.runLater(() -> inputButton.setDisable(false)); - Platform.runLater(() -> inputField.setText("")); - } - } - calculating = false; - } - }; - if (!calculating) { - calcThread = new Thread(calculator); - calcThread.setName("calcThread"); - calcThread.start(); - } + inputButton.setDisable(true); + stopButton.setDisable(false); + calculationThread = new Thread(CALCULATION_RUNNABLE); + calculationThread.start(); } @FXML - private void stopCalculation() { - calcThread.interrupt(); - calculating = false; - //Platform.runLater(() ->inputButton.setDisable(false)); + private void performStop(){ + if(calculationThread != null) + calculationThread.interrupt(); } @FXML diff --git a/src/main/java/org/nwapw/abacus/number/ComputationInterruptedException.java b/src/main/java/org/nwapw/abacus/number/ComputationInterruptedException.java new file mode 100644 index 0000000..cc3e9e1 --- /dev/null +++ b/src/main/java/org/nwapw/abacus/number/ComputationInterruptedException.java @@ -0,0 +1,16 @@ +package org.nwapw.abacus.number; + +/** + * Exception thrown when the computation is interrupted by + * the user. + */ +public class ComputationInterruptedException extends RuntimeException { + + /** + * Creates a new exception of this type. + */ + public ComputationInterruptedException(){ + super("Computation interrupted by user."); + } + +} diff --git a/src/main/java/org/nwapw/abacus/number/NaiveNumber.java b/src/main/java/org/nwapw/abacus/number/NaiveNumber.java index 2f97497..48beb1a 100755 --- a/src/main/java/org/nwapw/abacus/number/NaiveNumber.java +++ b/src/main/java/org/nwapw/abacus/number/NaiveNumber.java @@ -3,7 +3,7 @@ package org.nwapw.abacus.number; /** * An implementation of NumberInterface using a double. */ -public class NaiveNumber implements NumberInterface { +public class NaiveNumber extends NumberInterface { /** * The number zero. @@ -42,32 +42,32 @@ public class NaiveNumber implements NumberInterface { } @Override - public NumberInterface multiply(NumberInterface multiplier) { + public NumberInterface multiplyInternal(NumberInterface multiplier) { return new NaiveNumber(value * ((NaiveNumber) multiplier).value); } @Override - public NumberInterface divide(NumberInterface divisor) { + public NumberInterface divideInternal(NumberInterface divisor) { return new NaiveNumber(value / ((NaiveNumber) divisor).value); } @Override - public NumberInterface add(NumberInterface summand) { + public NumberInterface addInternal(NumberInterface summand) { return new NaiveNumber(value + ((NaiveNumber) summand).value); } @Override - public NumberInterface subtract(NumberInterface subtrahend) { + public NumberInterface subtractInternal(NumberInterface subtrahend) { return new NaiveNumber(value - ((NaiveNumber) subtrahend).value); } @Override - public NumberInterface negate() { + public NumberInterface negateInternal() { return new NaiveNumber(-value); } @Override - public NumberInterface intPow(int exponent) { + public NumberInterface intPowInternal(int exponent) { if (exponent == 0) { return NaiveNumber.ONE; } @@ -95,17 +95,17 @@ public class NaiveNumber implements NumberInterface { } @Override - public NumberInterface ceiling() { + public NumberInterface ceilingInternal() { return new NaiveNumber(Math.ceil(value)); } @Override - public NumberInterface floor() { + public NumberInterface floorInternal() { return new NaiveNumber(Math.floor(value)); } @Override - public NumberInterface fractionalPart() { + public NumberInterface fractionalPartInternal() { return new NaiveNumber(value - Math.floor(value)); } @@ -115,7 +115,7 @@ public class NaiveNumber implements NumberInterface { } @Override - public NumberInterface promoteTo(Class toClass) { + public NumberInterface promoteToInternal(Class toClass) { if (toClass == this.getClass()) return this; else if (toClass == PreciseNumber.class) { return new PreciseNumber(Double.toString(value)); diff --git a/src/main/java/org/nwapw/abacus/number/NumberInterface.java b/src/main/java/org/nwapw/abacus/number/NumberInterface.java index 835a335..7af5901 100755 --- a/src/main/java/org/nwapw/abacus/number/NumberInterface.java +++ b/src/main/java/org/nwapw/abacus/number/NumberInterface.java @@ -3,14 +3,22 @@ package org.nwapw.abacus.number; /** * An interface used to represent a number. */ -public interface NumberInterface { +public abstract class NumberInterface { + /** + * Check if the thread was interrupted and + * throw an exception to end the computation. + */ + private static void checkInterrupted(){ + if(Thread.currentThread().isInterrupted()) + throw new ComputationInterruptedException(); + } /** * The maximum precision to which this number operates. * * @return the precision. */ - int getMaxPrecision(); + public abstract int getMaxPrecision(); /** * Multiplies this number by another, returning @@ -19,7 +27,21 @@ public interface NumberInterface { * @param multiplier the multiplier * @return the result of the multiplication. */ - NumberInterface multiply(NumberInterface multiplier); + protected abstract NumberInterface multiplyInternal(NumberInterface multiplier); + + /** + * Multiplies this number by another, returning + * a new number instance. Also, checks if the + * thread has been interrupted, and if so, throws + * an exception. + * + * @param multiplier the multiplier + * @return the result of the multiplication. + */ + public final NumberInterface multiply(NumberInterface multiplier){ + checkInterrupted(); + return multiplyInternal(multiplier); + } /** * Divides this number by another, returning @@ -28,7 +50,21 @@ public interface NumberInterface { * @param divisor the divisor * @return the result of the division. */ - NumberInterface divide(NumberInterface divisor); + protected abstract NumberInterface divideInternal(NumberInterface divisor); + + /** + * Divides this number by another, returning + * a new number instance. Also, checks if the + * thread has been interrupted, and if so, throws + * an exception. + * + * @param divisor the divisor + * @return the result of the division. + */ + public final NumberInterface divide(NumberInterface divisor){ + checkInterrupted(); + return divideInternal(divisor); + } /** * Adds this number to another, returning @@ -37,7 +73,21 @@ public interface NumberInterface { * @param summand the summand * @return the result of the summation. */ - NumberInterface add(NumberInterface summand); + protected abstract NumberInterface addInternal(NumberInterface summand); + + /** + * Adds this number to another, returning + * a new number instance. Also, checks if the + * thread has been interrupted, and if so, throws + * an exception. + * + * @param summand the summand + * @return the result of the summation. + */ + public final NumberInterface add(NumberInterface summand){ + checkInterrupted(); + return addInternal(summand); + } /** * Subtracts another number from this number, @@ -46,7 +96,21 @@ public interface NumberInterface { * @param subtrahend the subtrahend. * @return the result of the subtraction. */ - NumberInterface subtract(NumberInterface subtrahend); + protected abstract NumberInterface subtractInternal(NumberInterface subtrahend); + + /** + * Subtracts another number from this number, + * a new number instance. Also, checks if the + * thread has been interrupted, and if so, throws + * an exception. + * + * @param subtrahend the subtrahend. + * @return the result of the subtraction. + */ + public final NumberInterface subtract(NumberInterface subtrahend){ + checkInterrupted(); + return subtractInternal(subtrahend); + } /** * Returns a new instance of this number with @@ -54,7 +118,21 @@ public interface NumberInterface { * * @return the new instance. */ - NumberInterface negate(); + protected abstract NumberInterface negateInternal(); + + + /** + * Returns a new instance of this number with + * the sign flipped. Also, checks if the + * thread has been interrupted, and if so, throws + * an exception. + * + * @return the new instance. + */ + public final NumberInterface negate(){ + checkInterrupted(); + return negateInternal(); + } /** * Raises this number to an integer power. @@ -62,7 +140,20 @@ public interface NumberInterface { * @param exponent the exponent to which to take the number. * @return the resulting value. */ - NumberInterface intPow(int exponent); + protected abstract NumberInterface intPowInternal(int exponent); + + /** + * Raises this number to an integer power. Also, checks if the + * thread has been interrupted, and if so, throws + * an exception. + * + * @param exponent the exponent to which to take the number. + * @return the resulting value. + */ + public final NumberInterface intPow(int exponent){ + checkInterrupted(); + return intPowInternal(exponent); + } /** * Compares this number to another. @@ -70,35 +161,70 @@ public interface NumberInterface { * @param number the number to compare to. * @return same as Integer.compare(); */ - int compareTo(NumberInterface number); + public abstract int compareTo(NumberInterface number); /** * Same as Math.signum(). * * @return 1 if this number is positive, -1 if this number is negative, 0 if this number is 0. */ - int signum(); + public abstract int signum(); /** * Returns the least integer greater than or equal to the number. * + * @return the least integer >= the number, if int can hold the value. + */ + protected abstract NumberInterface ceilingInternal(); + + /** + * Returns the least integer greater than or equal to the number. + * Also, checks if the thread has been interrupted, and if so, throws + * an exception. + * * @return the least integer bigger or equal to the number, if int can hold the value. */ - NumberInterface ceiling(); + public final NumberInterface ceiling(){ + checkInterrupted(); + return ceilingInternal(); + } /** * Return the greatest integer less than or equal to the number. * * @return the greatest integer smaller or equal the number, if int can hold the value. */ - NumberInterface floor(); + protected abstract NumberInterface floorInternal(); + + /** + * Return the greatest integer less than or equal to the number. + * Also, checks if the thread has been interrupted, and if so, throws + * an exception. + * + * @return the greatest int >= the number, if int can hold the value. + */ + public final NumberInterface floor(){ + checkInterrupted(); + return floorInternal(); + } /** * Returns the fractional part of the number. * * @return the fractional part of the number. */ - NumberInterface fractionalPart(); + protected abstract NumberInterface fractionalPartInternal(); + + /** + * Returns the fractional part of the number. + * Also, checks if the thread has been interrupted, + * and if so, throws an exception. + * @return the fractional part of the number. + */ + public final NumberInterface fractionalPart(){ + checkInterrupted(); + return fractionalPartInternal(); + } /** * Returns the integer representation of this number, discarding any fractional part, @@ -106,7 +232,7 @@ public interface NumberInterface { * * @return the integer value of this number. */ - int intValue(); + public abstract int intValue(); /** * Promotes this class to another number class. @@ -114,6 +240,19 @@ public interface NumberInterface { * @param toClass the class to promote to. * @return the resulting new instance. */ - NumberInterface promoteTo(Class toClass); + protected abstract NumberInterface promoteToInternal(Class toClass); + + /** + * Promotes this class to another number class. Also, checks if the + * thread has been interrupted, and if so, throws + * an exception. + * + * @param toClass the class to promote to. + * @return the resulting new instance. + */ + public final NumberInterface promoteTo(Class toClass) { + checkInterrupted(); + return promoteToInternal(toClass); + } } diff --git a/src/main/java/org/nwapw/abacus/number/PreciseNumber.java b/src/main/java/org/nwapw/abacus/number/PreciseNumber.java index 1baa867..abc657f 100755 --- a/src/main/java/org/nwapw/abacus/number/PreciseNumber.java +++ b/src/main/java/org/nwapw/abacus/number/PreciseNumber.java @@ -7,7 +7,7 @@ import java.math.RoundingMode; * A number that uses a BigDecimal to store its value, * leading to infinite possible precision. */ -public class PreciseNumber implements NumberInterface { +public class PreciseNumber extends NumberInterface { /** * The number one. @@ -52,27 +52,27 @@ public class PreciseNumber implements NumberInterface { } @Override - public NumberInterface multiply(NumberInterface multiplier) { + public NumberInterface multiplyInternal(NumberInterface multiplier) { return new PreciseNumber(this.value.multiply(((PreciseNumber) multiplier).value)); } @Override - public NumberInterface divide(NumberInterface divisor) { + public NumberInterface divideInternal(NumberInterface divisor) { return new PreciseNumber(value.divide(((PreciseNumber) divisor).value, this.getMaxPrecision(), RoundingMode.HALF_UP)); } @Override - public NumberInterface add(NumberInterface summand) { + public NumberInterface addInternal(NumberInterface summand) { return new PreciseNumber(value.add(((PreciseNumber) summand).value)); } @Override - public NumberInterface subtract(NumberInterface subtrahend) { + public NumberInterface subtractInternal(NumberInterface subtrahend) { return new PreciseNumber(value.subtract(((PreciseNumber) subtrahend).value)); } @Override - public NumberInterface intPow(int exponent) { + public NumberInterface intPowInternal(int exponent) { if (exponent == 0) { return PreciseNumber.ONE; } @@ -99,7 +99,7 @@ public class PreciseNumber implements NumberInterface { } @Override - public NumberInterface ceiling() { + public NumberInterface ceilingInternal() { String str = value.toPlainString(); int decimalIndex = str.indexOf('.'); if (decimalIndex != -1) { @@ -109,7 +109,7 @@ public class PreciseNumber implements NumberInterface { } @Override - public NumberInterface floor() { + public NumberInterface floorInternal() { String str = value.toPlainString(); int decimalIndex = str.indexOf('.'); if (decimalIndex != -1) { @@ -119,7 +119,7 @@ public class PreciseNumber implements NumberInterface { } @Override - public NumberInterface fractionalPart() { + public NumberInterface fractionalPartInternal() { String str = value.toPlainString(); int decimalIndex = str.indexOf('.'); if (decimalIndex != -1) { @@ -134,12 +134,12 @@ public class PreciseNumber implements NumberInterface { } @Override - public NumberInterface negate() { + public NumberInterface negateInternal() { return new PreciseNumber(value.negate()); } @Override - public NumberInterface promoteTo(Class toClass) { + public NumberInterface promoteToInternal(Class toClass) { if (toClass == this.getClass()) { return this; } diff --git a/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java b/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java index 6239ed9..5d35032 100644 --- a/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java +++ b/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java @@ -162,8 +162,10 @@ public class ShuntingYardParser implements Parser>, PluginListe @Override public TreeNode constructTree(List> tokens) { tokens = intoPostfix(new ArrayList<>(tokens)); + if(tokens == null) return null; Collections.reverse(tokens); - return constructRecursive(tokens); + TreeNode constructedTree = constructRecursive(tokens); + return tokens.size() == 0 ? constructedTree : null; } @Override diff --git a/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java b/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java index e82ca2e..c123caa 100755 --- a/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java +++ b/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java @@ -29,13 +29,9 @@ public class StandardPlugin extends Plugin { @Override protected NumberInterface applyInternal(NumberInterface[] params) { - if (Thread.currentThread().isInterrupted()) - return null; NumberInterface sum = params[0]; for (int i = 1; i < params.length; i++) { sum = sum.add(params[i]); - if (Thread.currentThread().isInterrupted()) - return null; } return sum; } @@ -51,8 +47,6 @@ public class StandardPlugin extends Plugin { @Override protected NumberInterface applyInternal(NumberInterface[] params) { - if (Thread.currentThread().isInterrupted()) - return null; return params[0].subtract(params[1]); } @@ -68,8 +62,6 @@ public class StandardPlugin extends Plugin { @Override protected NumberInterface applyInternal(NumberInterface[] params) { - if (Thread.currentThread().isInterrupted()) - return null; return params[0].negate(); } }); @@ -84,13 +76,9 @@ public class StandardPlugin extends Plugin { @Override protected NumberInterface applyInternal(NumberInterface[] params) { - if (Thread.currentThread().isInterrupted()) - return null; NumberInterface product = params[0]; for (int i = 1; i < params.length; i++) { product = product.multiply(params[i]); - if (Thread.currentThread().isInterrupted()) - return null; } return product; } @@ -106,8 +94,6 @@ public class StandardPlugin extends Plugin { @Override protected NumberInterface applyInternal(NumberInterface[] params) { - if (Thread.currentThread().isInterrupted()) - return null; return params[0].divide(params[1]); } }); @@ -125,19 +111,15 @@ public class StandardPlugin extends Plugin { @Override protected NumberInterface applyInternal(NumberInterface[] params) { - if (Thread.currentThread().isInterrupted()) - return null; if (params[0].signum() == 0) { return (new NaiveNumber(1)).promoteTo(params[0].getClass()); } NumberInterface factorial = params[0]; NumberInterface multiplier = params[0]; //It is necessary to later prevent calls of factorial on anything but non-negative integers. - while (!Thread.currentThread().isInterrupted() && (multiplier = multiplier.subtract(NaiveNumber.ONE.promoteTo(multiplier.getClass()))) != null && multiplier.signum() == 1) { + while ((multiplier = multiplier.subtract(NaiveNumber.ONE.promoteTo(multiplier.getClass()))).signum() == 1) { factorial = factorial.multiply(multiplier); } - if (Thread.currentThread().isInterrupted()) - return null; return factorial; /*if(!storedList.containsKey(params[0].getClass())){ storedList.put(params[0].getClass(), new ArrayList()); @@ -157,8 +139,6 @@ public class StandardPlugin extends Plugin { @Override protected NumberInterface applyInternal(NumberInterface[] params) { - if (Thread.currentThread().isInterrupted()) - return null; return params[0].multiply((new NaiveNumber(params[0].signum())).promoteTo(params[0].getClass())); } }; @@ -173,32 +153,26 @@ public class StandardPlugin extends Plugin { @Override protected NumberInterface applyInternal(NumberInterface[] params) { - if (Thread.currentThread().isInterrupted()) - return null; NumberInterface param = params[0]; int powersOf2 = 0; - NumberInterface check; - while (!Thread.currentThread().isInterrupted() && (check = FUNCTION_ABS.apply(param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())))) != null && (check.compareTo((new NaiveNumber(0.1)).promoteTo(param.getClass()))) >= 0) { - if ((check = param.subtract(NaiveNumber.ONE.promoteTo(param.getClass()))) != null && check.signum() == 1) { + while (FUNCTION_ABS.apply(param.subtract(NaiveNumber.ONE.promoteTo(param.getClass()))).compareTo(new NaiveNumber(0.1).promoteTo(param.getClass())) >= 0) { + if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() == 1) { param = param.divide(new NaiveNumber(2).promoteTo(param.getClass())); powersOf2++; - if ((check = param.subtract(NaiveNumber.ONE.promoteTo(param.getClass()))) == null || check.signum() != 1) { + if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() != 1) { break; //No infinite loop for you. } } else { param = param.multiply(new NaiveNumber(2).promoteTo(param.getClass())); powersOf2--; - if ((check = param.subtract(NaiveNumber.ONE.promoteTo(param.getClass()))) == null || check.signum() != 1) { + if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() != -1) { break; //No infinite loop for you. } } } - NumberInterface check2; - if (!Thread.currentThread().isInterrupted() && (check = getLog2(param)) != null && (check = check.multiply((new NaiveNumber(powersOf2).promoteTo(param.getClass())))) != null && (check2 = getLogPartialSum(param)) != null && (check = check.add(check2)) != null) - return check; - return null; + return getLog2(param).multiply((new NaiveNumber(powersOf2)).promoteTo(param.getClass())).add(getLogPartialSum(param)); } /** @@ -209,22 +183,16 @@ public class StandardPlugin extends Plugin { */ private NumberInterface getLogPartialSum(NumberInterface x) { - if (Thread.currentThread().isInterrupted()) - return null; NumberInterface maxError = getMaxError(x); x = x.subtract(NaiveNumber.ONE.promoteTo(x.getClass())); //Terms used are for log(x+1). NumberInterface currentNumerator = x, currentTerm = x, sum = x; int n = 1; - NumberInterface check; - while (!Thread.currentThread().isInterrupted() && (check = FUNCTION_ABS.apply(currentTerm)) != null && check.compareTo(maxError) > 0) { + while (FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0) { n++; - if ((currentNumerator = currentNumerator.multiply(x)) == null || (currentNumerator = currentNumerator.negate()) == null) - return null; + currentNumerator = currentNumerator.multiply(x).negate(); currentTerm = currentNumerator.divide(new NaiveNumber(n).promoteTo(x.getClass())); sum = sum.add(currentTerm); } - if (Thread.currentThread().isInterrupted()) - return null; return sum; } @@ -234,8 +202,6 @@ public class StandardPlugin extends Plugin { * @return the value of log(2) with the appropriate precision. */ private NumberInterface getLog2(NumberInterface number) { - if (Thread.currentThread().isInterrupted()) - return null; NumberInterface maxError = getMaxError(number); //NumberInterface errorBound = (new NaiveNumber(1)).promoteTo(number.getClass()); //We'll use the series \sigma_{n >= 1) ((1/3^n + 1/4^n) * 1/n) @@ -244,17 +210,13 @@ public class StandardPlugin extends Plugin { NumberInterface a = (new NaiveNumber(1)).promoteTo(number.getClass()), b = a, c = a; NumberInterface sum = NaiveNumber.ZERO.promoteTo(number.getClass()); int n = 0; - while (!Thread.currentThread().isInterrupted() && a.compareTo(maxError) >= 1) { + while (a.compareTo(maxError) >= 1) { n++; a = a.divide((new NaiveNumber(3)).promoteTo(number.getClass())); b = b.divide((new NaiveNumber(4)).promoteTo(number.getClass())); c = NaiveNumber.ONE.promoteTo(number.getClass()).divide((new NaiveNumber(n)).promoteTo(number.getClass())); - NumberInterface check; - if (a == null || (check = a.add(b)) == null || (check = check.multiply(c)) == null || (sum = sum.add(check)) == null) - return null; + sum = sum.add(a.add(b).multiply(c)); } - if (Thread.currentThread().isInterrupted()) - return null; return sum; } }; @@ -378,15 +340,11 @@ public class StandardPlugin extends Plugin { @Override protected NumberInterface applyInternal(NumberInterface[] params) { - if (Thread.currentThread().isInterrupted()) return null; - else if (params[0].compareTo(NaiveNumber.ZERO.promoteTo(params[0].getClass())) == 0) + if (params[0].compareTo(NaiveNumber.ZERO.promoteTo(params[0].getClass())) == 0) return NaiveNumber.ZERO.promoteTo(params[0].getClass()); else if (params[1].compareTo(NaiveNumber.ZERO.promoteTo(params[0].getClass())) == 0) return NaiveNumber.ONE.promoteTo(params[1].getClass()); - FUNCTION_EXP.apply(FUNCTION_LN.apply(FUNCTION_ABS.apply(params[0])).multiply(params[1])); - NumberInterface check = FUNCTION_LN.apply(FUNCTION_ABS.apply(params[0])); - if(check == null) return null; - return FUNCTION_EXP.apply(check.multiply(params[1])); + return FUNCTION_EXP.apply(FUNCTION_LN.apply(FUNCTION_ABS.apply(params[0])).multiply(params[1])); } }); /** @@ -524,8 +482,6 @@ public class StandardPlugin extends Plugin { * @return a number of numClass with value n factorial. */ public static NumberInterface factorial(Class numberClass, int n) { - if (Thread.currentThread().isInterrupted()) - return null; if (!FACTORIAL_LISTS.containsKey(numberClass)) { FACTORIAL_LISTS.put(numberClass, new ArrayList<>()); FACTORIAL_LISTS.get(numberClass).add(NaiveNumber.ONE.promoteTo(numberClass)); @@ -533,12 +489,10 @@ public class StandardPlugin extends Plugin { } ArrayList list = FACTORIAL_LISTS.get(numberClass); if (n >= list.size()) { - while (!Thread.currentThread().isInterrupted() && list.size() < n + 16) { + while (list.size() < n + 16) { list.add(list.get(list.size() - 1).multiply(new NaiveNumber(list.size()).promoteTo(numberClass))); } } - if (Thread.currentThread().isInterrupted()) - return null; return list.get(n); } @@ -578,8 +532,6 @@ public class StandardPlugin extends Plugin { } public static NumberInterface intPow(NumberInterface number, Class numberClass, NumberInterface exponent) { - if (Thread.currentThread().isInterrupted()) - return null; if (exponent.compareTo((new NaiveNumber(0)).promoteTo(numberClass)) == 0) { return (new NaiveNumber(1)).promoteTo(numberClass); } @@ -588,14 +540,10 @@ public class StandardPlugin extends Plugin { NumberInterface power = number; for (NumberInterface currentExponent = (new NaiveNumber(1)).promoteTo(numberClass); currentExponent.compareTo(exponent) < 0; currentExponent = currentExponent.add((new NaiveNumber(1)).promoteTo(numberClass))) { power = power.multiply(number); - if (Thread.currentThread().isInterrupted()) - return null; } if (takeReciprocal) { power = (new NaiveNumber(1)).promoteTo(numberClass).divide(power); } - if (Thread.currentThread().isInterrupted()) - return null; return power; } diff --git a/src/main/java/org/nwapw/abacus/tree/BinaryNode.java b/src/main/java/org/nwapw/abacus/tree/BinaryNode.java index 0ae6acf..6ec7b80 100644 --- a/src/main/java/org/nwapw/abacus/tree/BinaryNode.java +++ b/src/main/java/org/nwapw/abacus/tree/BinaryNode.java @@ -92,15 +92,10 @@ public class BinaryNode extends TreeNode { @Override public T reduce(Reducer reducer) { - if (Thread.currentThread().isInterrupted()) - return null; T leftReduce = left.reduce(reducer); T rightReduce = right.reduce(reducer); if (leftReduce == null || rightReduce == null) return null; - T a = reducer.reduceNode(this, leftReduce, rightReduce); - if (Thread.currentThread().isInterrupted()) - return null; - return a; + return reducer.reduceNode(this, leftReduce, rightReduce); } @Override diff --git a/src/main/java/org/nwapw/abacus/tree/FunctionNode.java b/src/main/java/org/nwapw/abacus/tree/FunctionNode.java index 0f939c8..a0ee26e 100644 --- a/src/main/java/org/nwapw/abacus/tree/FunctionNode.java +++ b/src/main/java/org/nwapw/abacus/tree/FunctionNode.java @@ -62,17 +62,12 @@ public class FunctionNode extends TreeNode { @Override public T reduce(Reducer reducer) { - if (Thread.currentThread().isInterrupted()) - return null; Object[] reducedChildren = new Object[children.size()]; for (int i = 0; i < reducedChildren.length; i++) { reducedChildren[i] = children.get(i).reduce(reducer); - if (Thread.currentThread().isInterrupted() || reducedChildren[i] == null) return null; + if (reducedChildren[i] == null) return null; } - T a = reducer.reduceNode(this, reducedChildren); - if (Thread.currentThread().isInterrupted()) - return null; - return a; + return reducer.reduceNode(this, reducedChildren); } @Override diff --git a/src/main/java/org/nwapw/abacus/tree/UnaryNode.java b/src/main/java/org/nwapw/abacus/tree/UnaryNode.java index 7956169..298d25d 100644 --- a/src/main/java/org/nwapw/abacus/tree/UnaryNode.java +++ b/src/main/java/org/nwapw/abacus/tree/UnaryNode.java @@ -33,14 +33,9 @@ public class UnaryNode extends TreeNode { @Override public T reduce(Reducer reducer) { - if (Thread.currentThread().isInterrupted()) - return null; Object reducedChild = applyTo.reduce(reducer); if (reducedChild == null) return null; - T a = reducer.reduceNode(this, reducedChild); - if (Thread.currentThread().isInterrupted()) - return null; - return a; + return reducer.reduceNode(this, reducedChild); } /** diff --git a/src/main/resources/abacus.fxml b/src/main/resources/abacus.fxml index 11ae276..495c654 100644 --- a/src/main/resources/abacus.fxml +++ b/src/main/resources/abacus.fxml @@ -35,7 +35,7 @@