Search code examples
javamathcalculator

Modifying Calculator to accept negative numbers


My current calculator can compute basic operators with respect to orders of operations (*, -, /, +) but doesn't accept negative numbers. However, it does work with (-2 * 2) and returns -4 as expected but doesn't work if the first number is not negative (2 * -2 returns 4). I have tried turning the "-" operator to make the 2nd operand negative (so it's just all addition and no subtraction if that makes sense) but I couldn't get it to work. Thank you for your time.

Here's my current code:

java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("Enter a math expression: ");
        String expression = scanner.nextLine();

        double result = 0;
        double currentNumber = 0;
        double multiplier = 1;
        boolean isNewNumber = true;
        boolean hasDecimal = false;
        double decimalMultiplier = 0.1;

        for (int i = 0; i < expression.length(); i++) {
            String currentSymbol = expression.substring(i, i + 1);

            if ("0123456789".indexOf(currentSymbol) != -1) {
                if (hasDecimal) {
                    currentNumber = currentNumber + Double.parseDouble(currentSymbol) * decimalMultiplier;
                    decimalMultiplier /= 10;
                } else {
                    currentNumber = currentNumber * 10 + Double.parseDouble(currentSymbol);
                    isNewNumber = true;
                }
            } else if (currentSymbol.equals(".")) {
                hasDecimal = true;\
            } else if ("+-*/".indexOf(currentSymbol) != -1) {
                if (isNewNumber) {
                    if (currentSymbol.equals("+")) {
                        result = result + currentNumber * multiplier;
                    } else if (currentSymbol.equals("-")) {
                        if (i == 0 || "+-*/".indexOf(expression.substring(i - 1, i)) != -1) {
                            multiplier = -1;
                        } else {
                            result = result + currentNumber * multiplier;
                            multiplier = -1;
                        }
                    } else if (currentSymbol.equals("*")) {
                        multiplier = multiplier * currentNumber;
                    } else if (currentSymbol.equals("/")) {
                            multiplier = multiplier / currentNumber;
                    }
                    currentNumber = 0;
                    isNewNumber = false;
                    hasDecimal = false;
                    decimalMultiplier = 0.1;
                }
            }
        }

        result = result + currentNumber * multiplier;
        System.out.println("Result: " + result);
    }
}

Solution

  • There is not much required to get this to work, just 7 lines of code.

    All I did was add a check for - right after another operator was found. Since the isNewNumber boolean was cleared after performing a mathematical operation, there was a gap to check if - came up again when the program was expecting a number.

    The complete code with changes to make the expression 2*-2 get result -4.0

    import java.util.Scanner;
    
    public class StackCalc {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
    
            System.out.print("Enter a math expression: ");
            String expression = scanner.nextLine();
    
            double result = 0;
            double currentNumber = 0;
            double multiplier = 1;
            boolean isNewNumber = true;
            boolean hasDecimal = false;
            double decimalMultiplier = 0.1;
            boolean negNumber = false;
    
            for (int i = 0; i < expression.length(); i++) {
                String currentSymbol = expression.substring(i, i + 1);
    
                if ("0123456789".indexOf(currentSymbol) != -1) {
                    if (hasDecimal) {
                        currentNumber = currentNumber + Double.parseDouble(currentSymbol) * decimalMultiplier;
                        decimalMultiplier /= 10;
                    } else { // apply neg
                        double doubleSymbol = Double.parseDouble(currentSymbol);
                        if (negNumber) {
                           doubleSymbol = doubleSymbol * -1;
                        }
                        currentNumber = currentNumber * 10 + doubleSymbol;
                        isNewNumber = true;
                    }
                } else if (currentSymbol.equals(".")) {
                    hasDecimal = true;
                } else if ("+-*/".indexOf(currentSymbol) != -1) {
                    if (isNewNumber) {
                        if (currentSymbol.equals("+")) {
                            result = result + currentNumber * multiplier;
                        } else if (currentSymbol.equals("-")) {
                            if (i == 0 || "+-*/".indexOf(expression.substring(i - 1, i)) != -1) {
                                multiplier = -1;
                            } else {
                                result = result + currentNumber * multiplier;
                                multiplier = -1;
                            }
                        } else if (currentSymbol.equals("*")) {
                            multiplier = multiplier * currentNumber;
                        } else if (currentSymbol.equals("/")) {
                            multiplier = multiplier / currentNumber;
                        }
                        currentNumber = 0;
                        isNewNumber = false;
                        hasDecimal = false;
                        decimalMultiplier = 0.1;
                        negNumber = false;
                    } else {
                        negNumber = true;
                    }
                }
            }
    
            result = result + currentNumber * multiplier;
            System.out.println("Result: " + result);
        }
    }
    

    Annotation: Oddly enough, I have access to a library that does this type of operation: convert strings into expressions and run the calculation. It was hard not to post this here and explain how to use it.