HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

A (late) Simple Calculator

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simplecalculatorlate

Problem

As I was looking through my past questions, I noticed my really old calculator question (here and here). Considering it looked like a huge mess, I decided to rewrite it. Coincidentally, the April 2015 Community Challenge was to implement a simple calculator. It might be a bit late, but here it is:

```
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

public class Calculator {

private static final Pattern NUMBER_PATTERN = Pattern
.compile("\\d+(\\.\\d+)?");

public static double calculate(String equation) {
return calculate(equation, Operation.getLastInPrecedence());
}

private static double calculate(String equation, Operation currentOp) {
Operation nextOp = currentOp.getPreviousInPrecedence();
if (NUMBER_PATTERN.matcher(equation).matches()) {
return Double.parseDouble(equation);
}
String[] equationParts = equation.split("\\s*"
+ Pattern.quote(Character.toString(currentOp.getSymbol()))
+ "\\s*");
double result;
if (nextOp == null) {
// Last operation
result = Math.pow(Integer
.parseInt(equationParts[equationParts.length - 2]), Integer
.parseInt(equationParts[equationParts.length - 1]));
for (int i = equationParts.length - 3; i >= 0; i--) {
result = Math.pow(Integer.parseInt(equationParts[i]), result);
}
} else {
result = calculate(equationParts[0], nextOp);
for (int i = 1; i operations = new HashMap<>();

static {
operations.put(ADD.precedence, ADD);
operations.put(SUBTRACT.precedence, SUBTRACT);
operations.put(MULTIPLY.precedence, MULTIPLY);
operations.put(DIVIDE.precedence, DIVIDE);
operations.put(POW.precedence, POW);
}

private final char symbol;
private final int precedence;

private Operation(char symbol, int

Solution

I have doubts about your unit tests — did you run them?

  • The test runner can't run your test unless it is public.



  • The class name Test collides with the org.junit.Test annotation.



  • For all the tests, I got java.lang.AssertionError: Use assertEquals(expected, actual, delta) to compare floating-point numbers — you need to specify a tolerance.



In addition, your test coverage is spotty.

  • You mentioned your concern about right-to-left associativity for the ^ operator, so why didn't you test for that?



  • Is 1 + 1 / 2 equal to 1.5 (standard precedence rules) or 1.0 (cheap calculator)?



  • Is 12 / 2 / 3 equal to 2.0 (standard associativity rules)? Your code evaluates it to 3.0, failing this test.



As for the calculator itself, I think it would be worthwhile to implement support for parentheses as well. Otherwise, there's no way to override the order of operations.

Context

StackExchange Code Review Q#90850, answer score: 7

Revisions (0)

No revisions yet.