Click here to Skip to main content
15,559,455 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I am pretty sure that this code doesn't work with negative numbers but I got it from stackoverflow and it is beyond my understanding so I don't even know how to start adding in the ability to use negative numbers. sorry because of copy paste form my project indentation got kind of screwed up

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) {
                return true;
            return false;

        twovars parse() {
            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();
            } 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);

What I have tried:

I don't really understand how the code itself works so I haven't tried anything. I am actively reading through it trying to make sense of it but I am relatively new to Java so there are a bunch of things here that I don't understand.
Updated 8-Jun-21 19:30pm
Richard MacCutchan 9-Jun-21 4:22am    
Ask the person in StackOverflow who gave you the code.

1 solution

While we are more than willing to help those that are stuck, that doesn't mean that we are here to do it all for you! We can't do all the work, you are either getting paid for this, or it's part of your grades and it wouldn't be at all fair for us to do it all for you.

So we need you to do the work, and we will help you when you get stuck. That doesn't mean we will give you a step by step solution you can hand in!
Start by explaining where you are at the moment, and what the next step in the process is. Then tell us what you have tried to get that next step working, and what happened when you did.

Getting code from SO is not a good way to learn anything: and if you can't understand it, then that's probably because you don't know how to write code yet. Which is a skill, and like all skills it only develops by practice: you can watch people riding bicycles all you like, but that won't teach you to ride one yourself - you are going to fall off until you develop the skill and body reflexes to stay upright. Same thing with coding: read codee all you like, you still won't know how to write it. Try to write it and you learn the skill.

If you are having problems getting started at all, then this may help: How to Write Code to Solve a Problem, A Beginner's Guide[^]
Share this answer

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900