{"id":3,"date":"2005-11-12T08:16:02","date_gmt":"2005-11-12T16:16:02","guid":{"rendered":"http:\/\/www.viscerallogic.com\/programming\/blog\/2006\/11\/17\/numerical-expression-solver-in-java\/"},"modified":"2013-01-07T18:58:58","modified_gmt":"2013-01-08T02:58:58","slug":"numerical-expression-solver-in-java","status":"publish","type":"post","link":"https:\/\/www.viscerallogic.com\/programming\/blog\/numerical-expression-solver-in-java\/","title":{"rendered":"Numerical Expression Solver in Java"},"content":{"rendered":"<p>This tutorial will show you how to write a Java program that takes a string input such as &#8220;3 + 4^2*7.5E-1*sin(22)&#8221; and convert it into a numerical answer, 2.893784 in this case, which you can use for whatever purpose you like.<!--more--><\/p>\n<p>This Java Applet utilizes the <em>Expression<\/em> class that you will be creating.<\/p>\n<p>We will accomplish this by parsing the input string for tokens that we recognize, and then removing them from the input string by using the <code>substring()<\/code> function. Here is the initial code for the file <em>Expression.java<\/em>:<\/p>\n<blockquote>\n<pre><code>\nimport java.util.*;\n\npublic class Expression{\n\t\/*\n\t* Strings used for storing expression.\n\t*\/\n\tString s, x;\n\n\t\/*\n\t* Term evaluator for number literals.\n\t*\/\n\tdouble term(){\n\t\t\/\/ insert code here\n\t}\n\n\t\/*\n\t* Public access method to evaluate this expression.\n\t*\/\n\tpublic double evaluate(){\n\t\ts = x.intern();\n\t\treturn term();\n\t}\n\n\t\/*\n\t* Creates new Expression.\n\t*\/\n\tpublic Expression( String s ){\n\t\t\/\/ remove white space, assume only spaces or tabs\n\t\tStringBuffer b = new StringBuffer();\n\t\tStringTokenizer t = new StringTokenizer( s, \" \" );\n\t\twhile( t.hasMoreElements() )\n\t\t\tb.append( t.nextToken() );\n\t\tt = new StringTokenizer( b.toString(), \"\\t\" );\n\t\tb = new StringBuffer();\n\t\twhile( t.hasMoreElements() )\n\t\t\tb.append( t.nextToken() );\n\n\t\tx = b.toString();\n\t}\n\n\t\/*\n\t* The String value of this Expression.\n\t*\/\n\tpublic String toString(){\n\t\treturn x.intern();\n\t}\n\n\t\/*\n\t* Test our Expression class by evaluating the command-line\n\t* argument and then returning.\n\t*\/\n\tpublic static void main( String[] args ){\n\t\tExpression e = new Expression( args[0] );\n\t\tSystem.out.println( e + \" = \" + e.evaluate() );\n\t}\n}\n<\/code><\/pre>\n<\/blockquote>\n<p>We import the <em>java.util.*<\/em> classes because we will be using a <em>StringTokenizer<\/em> in some places. The <code>Expression()<\/code> constructor takes a string as an argument, removes any white space, and stores the result in the variable <em>x<\/em>. The <code>toString()<\/code> function very simply returns a copy of <em>x<\/em>. The <code>evaluate()<\/code> function makes a copy of the string, because it gets modified in our processing code, and calls <code>term()<\/code> to search for a numerical valule. Finally, the <code>main()<\/code> function takes an input string from the user, creates an <em>Expression<\/em> with it, evaluates it, and returns the result.<\/p>\n<p>Let&#8217;s start by filling in the <code>term()<\/code> function.<\/p>\n<blockquote>\n<pre><code>\n\tdouble term(){\n\t\tdouble ans = 0;\n\n\t\tboolean neg = false;\n\t\tif( s.charAt( 0 ) == '-' ){\n\t\t\tneg = true;\n\t\t\ts = s.substring( 1 );\n\t\t}\n\n\t\tStringBuffer temp = new StringBuffer();\n\t\twhile( s.length() &gt; 0 &amp;&amp; Character.isDigit( s.charAt( 0 ) ) ){\n\t\t\ttemp.append(Integer.parseInt( \"\" + s.charAt( 0 ) ));\n\t\t\ts = s.substring( 1 );\n\t\t}\n\t\tif( s.length() &gt; 0 &amp;&amp; s.charAt( 0 ) == '.' ){\n\t\t\ttemp.append( '.' );\n\t\t\ts = s.substring( 1 );\n\t\t\twhile( s.length() &gt; 0 &amp;&amp; Character.isDigit( s.charAt( 0 ) ) ){\n\t\t\t\ttemp.append(Integer.parseInt( \"\" + s.charAt( 0 ) ));\n\t\t\t\ts = s.substring( 1 );\n\t\t\t}\n\t\t}\n\t\tif( s.length() &gt; 0 &amp;&amp; (s.charAt(0) == 'e' || s.charAt(0) == 'E') ){\n\t\t\ttemp.append( 'e' );\n\t\t\ts = s.substring( 1 );\n\t\t\ttemp.append( s.charAt( 0 ) );\n\t\t\ts = s.substring( 1 );\n\t\t\twhile( s.length() &gt; 0 &amp;&amp; Character.isDigit( s.charAt( 0 ) ) ){\n\t\t\t\ttemp.append(Integer.parseInt( \"\" + s.charAt( 0 ) ));\n\t\t\t\ts = s.substring( 1 );\n\t\t\t}\n\t\t}\n\t\tans = Double.valueOf( temp.toString() ).doubleValue();\n\n\t\tif( neg )\n\t\t\tans *= -1;\n\n\t\treturn ans;\n\t}\n\n<\/code><\/pre>\n<\/blockquote>\n<p>This function is capable of reading integers or floating point numbers, including a leading minus sign, decimal point, and exponential notation. It starts by declaring a double in which we will store our result. The first block of code checks to see if the first character is a minus sign. If so, it eats that character with the <code>s = s.substring( 1 )<\/code> call, and sets the variable <em>neg<\/em> to true. It is because of this method of using <code>substring()<\/code> that we needed the extra string variable <em>s<\/em> in the class.<\/p>\n<p>Next <code>term()<\/code> creates a <em>StringBuffer<\/em> and begins to read one character at a time from the string <em>s<\/em> and append it if it is a digit, also removing it from <em>s<\/em> if it is a digit. Once we have read all the digits, we check to see if the next character is a period. If so, we remove it and append it, and then continue reading digits. When we run out of digits again, or the first time if there was no decimal point, we check to see if the next character is an &#8216;e&#8217; or &#8216;E&#8217; for exponential notation. If so, we remove and append it. We also remove and append the next character. We do this under the assumption that the input is valid, and will therefore consist of an integer following the exponential sign. This method takes care of it whether it is a digit or a minus sign. Then we read any more digits that are contained in the exponential part.<\/p>\n<p>Once we have done this, our <em>StringBuffer, temp<\/em> has the full string value of the number, so we convert it to a <em>double<\/em>, multiply it by -1 if we found a minus sign as the very first character above, and return it.<\/p>\n<p>If you now compile and run <em>Expression<\/em>, it will correctly interpret strings such as &#8220;3&#8221;, &#8220;3.4&#8221;, &#8220;-267&#8221;, &#8220;.314159E1&#8221;, or &#8220;-.01E-12&#8221;.<\/p>\n<p>OK, now let&#8217;s include the capability to solve addition problems. Change the line <code>last = term();<\/code> in the <code>evaulate()<\/code> function to <code>last = add();<\/code> and then insert the following function into your file:<\/p>\n<blockquote>\n<pre><code>\n\t\/*\n\t* Addition, subtraction expression solver.\n\t*\/\n\tdouble add(){\n\t\tdouble ans = term();\n\t\twhile( s.length() &gt; 0 ){\n\t\t\tif( s.charAt( 0 ) == '+' ){\n\t\t\t\ts = s.substring( 1 );\n\t\t\t\tans += term();\n\t\t\t} else if( s.charAt( 0 ) == '-' ){\n\t\t\t\ts = s.substring( 1 );\n\t\t\t\tans -= term();\n\t\t\t} else{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn ans;\n\t}\n<\/code><\/pre>\n<\/blockquote>\n<p>The <code>add()<\/code> function first reads a number by calling the <code>term()<\/code> function. If that number is all the input, that is fine, <code>add()<\/code> will return that function. But if that is not all the input, it checks for a + or a &#8211; sign, removes that character from the string, reads the next number, performs the appropriate action, and continues in this way until it has read the entire string (or encountered an error). It then returns the answer.<\/p>\n<p>Now when you compile <em>Expression.java<\/em>, it can handle not only single numbers, but also addition and subtraction, such as &#8220;1+2&#8221;, or &#8220;-1.3e-1 + 9.7&#8221;. As you can see, the spaces in the last example don&#8217;t affect anything because we stripped them out in the constructor function. Also, the lowercase &#8216;e&#8217; works just as well as the uppercase &#8216;E&#8217;.<\/p>\n<p>Now replace the three occurrences of <code>term()<\/code> in the <code>add()<\/code> function with <code>mul()<\/code>, which will handle our multiplication functionality. The <code>mul()<\/code> function is as follows:<\/p>\n<blockquote>\n<pre><code>\n\t\/*\n\t* Multiplication, division expression solver.\n\t*\/\n\tdouble mul(){\n\t\tdouble ans = term();\n\t\twhile( s.length() &gt; 0 ){\n\t\t\tif( s.charAt( 0 ) == '*' ){\n\t\t\t\ts = s.substring( 1 );\n\t\t\t\tans *= term();\n\t\t\t} else if( s.charAt( 0 ) == '\/' ){\n\t\t\t\ts = s.substring( 1 );\n\t\t\t\tans \/= term();\n\t\t\t} else break;\n\t\t}\n\t\treturn ans;\n\t}\n<\/code><\/pre>\n<\/blockquote>\n<p>Like the <code>add()<\/code> function, the <code>mul()<\/code> function calls <code>term()<\/code> and then checks for multiplication or division operators. When it has run out, it returns to the <code>add()<\/code> function, which may then read in another portion of the string with additional numbers or multiplication.<\/p>\n<p>You can now compile <em>Expression<\/em> and it will interpret and solve such strings as &#8220;1+2*3+4&#8221;, or &#8220;-1-2.e-4*-2E3+12&#8221;, giving the proper output for standard operator precedence.<\/p>\n<p>We will now add trigonometric function capability. Replace the three occurrences of <code>term()<\/code> in the above <code>mul()<\/code> function with the call <code>trig()<\/code>. The <code>trig()<\/code> function is:<\/p>\n<blockquote>\n<pre><code>\n\t\/*\n\t* Trigonometric function solver.\n\t*\/\n\tdouble trig(){\n\t\tdouble ans = 0;\n\t\tboolean found = false;\n\t\tif( s.indexOf( \"sin\" ) == 0 ){\n\t\t\ts = s.substring( 3 );\n\t\t\tans = Math.sin( trig() );\n\t\t\tfound = true;\n\t\t} else if( s.indexOf( \"cos\" ) == 0 ){\n\t\t\ts = s.substring( 3 );\n\t\t\tans = Math.cos( trig() );\n\t\t\tfound = true;\n\t\t} else if( s.indexOf( \"tan\" ) == 0 ){\n\t\t\ts = s.substring( 3 );\n\t\t\tans = Math.tan( trig() );\n\t\t\tfound = true;\n\t\t}\n\t\tif( !found ){\n\t\t\tans = term();\n\t\t}\n\t\treturn ans;\n\t}\n<\/code><\/pre>\n<\/blockquote>\n<p>This function checks to see if the first part of the string is one of its recognized trig functions, and if so applies it and recurses, calling <code>trig()<\/code> again. When it no longer reads a function name, it assumes it is just a number, and calls term.<\/p>\n<p>After compiling, you can evaluate expressions such as &#8220;sin 12&#8221;, or &#8220;tan -3.4e-1&#8221;, or &#8220;sin cos 3&#8221; (the sine of the cosine of 3, hard to read since we haven&#8217;t added parentheses yet).<\/p>\n<p>The next operator we will add is the exponentiation operator, ^. Replace the call to <code>term()<\/code> in the above <code>trig()<\/code> function with <code>exp()<\/code>, and add that function to your file:<\/p>\n<blockquote>\n<pre><code>\n\t\/*\n\t* Exponentiation solver.\n\t*\/\n\tdouble exp(){\n\t\tboolean neg = false;\n\t\tif( s.charAt( 0 ) == '-' ){\n\t\t\tneg = true;\n\t\t\ts = s.substring( 1 );\n\t\t}\n\t\tdouble ans = term();\n\t\twhile( s.length() &gt; 0 ){\n\t\t\tif( s.charAt( 0 ) == '^' ){\n\t\t\t\ts = s.substring( 1 );\n\t\t\t\tboolean expNeg = false;\n\t\t\t\tif( s.charAt( 0 ) == '-' ){\n\t\t\t\t\texpNeg = true;\n\t\t\t\t\ts = s.substring( 1 );\n\t\t\t\t}\n\t\t\t\tdouble e = term();\n\t\t\t\tif( ans &lt; 0 ){\t\t\/\/ if it's negative\n\t\t\t\t\tdouble x = 1;\n\t\t\t\t\tif( Math.ceil(e) == e ){\t\/\/ only raise to an integer\n\t\t\t\t\t\tif( expNeg )\n\t\t\t\t\t\t\te *= -1;\n\t\t\t\t\t\tif( e == 0 )\n\t\t\t\t\t\t\tans = 1;\n\t\t\t\t\t\telse if( e &gt; 0 )\n\t\t\t\t\t\t\tfor( int i = 0; i &lt; e; i++ )\n\t\t\t\t\t\t\t\tx *= ans;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tfor( int i = 0; i &lt; -e; i++ )\n\t\t\t\t\t\t\t\tx \/= ans;\n\t\t\t\t\t\tans = x;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tans = Math.log(-1);\t\/\/ otherwise make it NaN\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( expNeg )\n\t\t\t\t\tans = Math.exp( -e*Math.log( ans ) );\n\t\t\t\telse\n\t\t\t\t\tans = Math.exp( e*Math.log( ans ) );\n\t\t\t} else\n\t\t\t\tbreak;\n\t\t}\n\t\tif( neg )\n\t\t\tans *= -1;\n\t\treturn ans;\n\t}\n<\/code><\/pre>\n<\/blockquote>\n<p>As you can see, we have moved the checking for a negative value into the <code>exp()<\/code> function because exponentiation has higher precedence, so remove the indicated lines from the term() function. This function is somewhat complicated because we can only raise negative numbers to integral powers. Until you code the next function you won&#8217;t be able to raise negative numbers to anything, however, because exponentiation has precedence, so the negative will apply to the result.<\/p>\n<p>Now the <em>Expression<\/em> class is fully capable of parsing and evaluating such strings as &#8220;sin 2^2&#8221; or even &#8220;2^3^-4&#8221;. Of course, it can also still handle those complicated decimal and exponential notation numbers with all this functionality.<\/p>\n<p>We are almost done now. The final step is to allow for parentheses. Replace the two calls to <code>term()<\/code> in <code>exp()<\/code> with calls to <code>paren()<\/code>, and put the following function into your file:<\/p>\n<blockquote>\n<pre><code>\n\t\/*\n\t* Parentheses solver.\n\t*\/\n\tdouble paren(){\n\t\tdouble ans;\n\t\tif( s.charAt( 0 ) == '(' ){\n\t\t\ts = s.substring( 1 );\n\t\t\tans = add();\n\t\t\ts = s.substring( 1 );\t\/\/ we assume this is a ')'\n\t\t} else {\n\t\t\tans = term();\n\t\t}\n\t\treturn ans;\n\t}\n<\/code><\/pre>\n<\/blockquote>\n<p>A parentheses-enclosed block has the same precedence as a single number, which is why this function checks for a ( ), or just a number. If the parentheses are present, it recurses back to the <code>add()<\/code> function because any expression is allowable inside parentheses.<\/p>\n<p>The <em>Expression<\/em> class is now fully functional. It properly handles operator precedence and notation.  You could also add additional functions to the <code>trig()<\/code> function, such as the inverse trigonometric functions, or logarithm or natural log, or even your own arbitrary function. The example given at the beginning of this page, &#8220;3 + 4^2*7.5E-1*sin(22)&#8221;, which involves every function we added to <em>Expression<\/em>, may now be solved.<\/p>\n<p>You can download the finished file <a href=\"http:\/\/www.viscerallogic.com\/programing\/expression1\/Expression.java\">here<\/a>.<br \/>\nThe applet code is available <a href=\"http:\/\/www.viscerallogic.com\/programing\/expression1\/ExpressionApplet.java\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial will show you how to write a Java program that takes a string input such as &#8220;3 + 4^2*7.5E-1*sin(22)&#8221; and convert it into a numerical answer, 2.893784 in this case, which you can use for whatever purpose you like.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[4,2],"tags":[],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9npkn-3","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":4,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/variables-and-graphical-plots-in-java\/","url_meta":{"origin":3,"position":0},"title":"Variables and Graphical Plots in Java","date":"November 17, 2005","format":false,"excerpt":"This tutorial builds on the Numerical Expression Solver tutorial, adding textual variables such as \"e\" or \"pi\", and custom ones. Then you will create an applet that takes advantage of this new functionality by creating a graphical representation of an arbitrary expression at each point in space. This applet is\u2026","rel":"","context":"In &quot;Java&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":90,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-iv\/","url_meta":{"origin":3,"position":1},"title":"BASIC Interpreter, Part IV","date":"September 7, 2018","format":false,"excerpt":"This is a continuation of Part III. This time we will add some mathematical operators, the ability to save and load programs, and support numerical variables. To enable mathematical operations, we will create a subclass of DoubleExpression that takes two DoubleExpressions as inputs, as well as a character code signifying\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":72,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpeter-part-iii\/","url_meta":{"origin":3,"position":2},"title":"BASIC Interpeter, Part III","date":"September 7, 2018","format":false,"excerpt":"This is a continuation of Part II. In this part, we will add support for numerical as well as string expressions, support multiple expression in a PRINT statement, and add functionality for deleting program lines. Let's start with the Basic class header file, basic.h. All we need to do here\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":46,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-ii\/","url_meta":{"origin":3,"position":3},"title":"BASIC Interpreter, Part II","date":"September 7, 2018","format":false,"excerpt":"This is a continuation of Part I. In Part II, we will add functionality to store and run BASIC programs, although still limited to the PRINT statement. We will also be adding a LIST statement to print out the currently stored program. We will be adding a number of new\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":131,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-vi\/","url_meta":{"origin":3,"position":4},"title":"BASIC Interpreter, Part VI","date":"September 7, 2018","format":false,"excerpt":"This is a continuation of Part V. In the previous section, we added support for the GOTO statement. Since we don't yet have any control logic, that is not very useful, but it does lay the infrastructure for one of the features we will add this time: IF-THEN. We will\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":111,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-v\/","url_meta":{"origin":3,"position":5},"title":"BASIC Interpreter, Part V","date":"September 7, 2018","format":false,"excerpt":"This is a continuation of Part IV. In Part V we will add support for parentheses in mathematical expressions, add the GOTO and END statements, and implement the remaining program storage statements: CATALOG, SCRATCH, and RENAME. Now that we have a framework for supporting numerical operations, adding parentheses is not\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/3"}],"collection":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/comments?post=3"}],"version-history":[{"count":2,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/3\/revisions"}],"predecessor-version":[{"id":11,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/3\/revisions\/11"}],"wp:attachment":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/media?parent=3"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/categories?post=3"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/tags?post=3"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}