# How to get this code to work with negative numbers Java

I have a function for evaluating equations in the form of strings but I don’t think (I didn’t write it and I am not good enough at Java to understand it yet) that it works with negative numbers. Is there either a better way to implement this same functionality (evaluating equations in the form of strings and also having trig functions) or a way to get the code to work with negatives? This is all in Java.

``````    public static twovars eval(final String str) {
return new Object() {
int pos = -1, ch;
void nextChar() {
ch = (++pos < str.length()) ? str.charAt(pos) : -1;
}

boolean eat(int charToEat) {
while (ch == ' ') nextChar();
if (ch == charToEat) {
nextChar();
return true;
}
return false;
}

twovars parse() {
nextChar();
twovars b = parseExpression();
double x = b.getDub();
if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
return new twovars(b.getBool(), x);
}

// Grammar:
// expression = term | expression `+` term | expression `-` term
// term = factor | term `*` factor | term `/` factor
// factor = `+` factor | `-` factor | `(` expression `)`
//        | number | functionName factor | factor `^` factor

twovars parseExpression() {
twovars b = parseFactor();
double x = b.getDub();
for (;;) {
if      (eat('+')) x += parseTerm().getDub(); // addition
else if (eat('-')) x -= parseTerm().getDub(); // subtraction
else return new twovars(false, x);
}
}

twovars parseTerm() {
twovars b = parseFactor();
double x = b.getDub();
for (;;) {
if      (eat('*')) x *= parseFactor().getDub(); // multiplication
else if (eat('/')) {
if(parseFactor().getDub() != 0) x /= parseFactor().getDub();
else return new twovars(true, 0);
} // division
else return new twovars(false, x);
}
}

twovars parseFactor() {
if (eat('+')) return new twovars(false, parseFactor().getDub()); // unary plus
if (eat('-')) return new twovars(false, -parseFactor().getDub()); // unary minus
double x;
int startPos = this.pos;
if (eat('(')) { // parentheses
x = parseExpression().getDub();
eat(')');
} else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
x = Double.parseDouble(str.substring(startPos, this.pos));
} else if (ch >= 'a' && ch <= 'z') { // functions
while (ch >= 'a' && ch <= 'z') nextChar();
String func = str.substring(startPos, this.pos);
x = parseFactor().getDub();
if (func.equals("sqrt")) x = Math.sqrt(x);
else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
else if (func.equals("tan")) {
if(x % Math.PI == 0) x = Math.tan(Math.toRadians(x));
else return new twovars(true, x);
}
else if (func.equals("csc")) x = 1/Math.sin(Math.toRadians(x));
else if (func.equals("sec")) x = 1/Math.cos(Math.toRadians(x));
else if (func.equals("cot")) x = 1/Math.tan(Math.toRadians(x));
else if (func.equals("arcsin")) {
if (x>1 || x<1) x = Math.asin(Math.toRadians(x));
else return new twovars(true, x);
}
else if (func.equals("arccos")) {
if(x>1 || x<1) x = Math.acos(Math.toRadians(x));
else return new twovars(true, x);
}
else if (func.equals("arctan")) x = Math.atan(Math.toRadians(x));
else if (func.equals("log")) {
if(x>0) x = Math.log(x);
else return new twovars(true, x);
}
else throw new RuntimeException("Unknown function: " + func);
} else if (ch >= 'A' && ch <= 'Z') { // named constants
while (ch >= 'A' && ch <= 'Z') nextChar();
String s = str.substring(startPos,this.pos);
if (s.equals("PI")) {
x = Math.PI;
} else if (s.equals("E")) {
x = Math.E;
} else {
throw new RuntimeException("Invalid constant: "+s);
}
} else {
throw new RuntimeException("Unexpected: " + (char)ch);
}

if (eat('^')) x = Math.pow(x, parseFactor().getDub()); // exponentiation

return new twovars(false, x);
}
}.parse();
``````