0

I am trying to develop an advanced math expression calculator in Java. My goal is that calculator can determinate expressions like these:

2 * 6^( log(123) - sin(7)^cos(2) )

lim( (5x^2) / x , x -> 1)
.
.
.

Is there anything (default function, external library) for this in Java or C++?

gg tty
  • 51
  • 7
  • 2
    Yes , lim means limit – gg tty Jan 07 '15 at 14:59
  • 1
    @Christian he wants to evaluate math expressions. Nothing to do with regex. – ale64bit Jan 07 '15 at 15:00
  • So does that mean x->1? Is this your query? http://www.wolframalpha.com/input/?i=limit+5x%5E2+as+x-%3E1 – Sid Jan 07 '15 at 15:01
  • @ggtty You want a CAS (Computer Algebra System) for symbolic computations. There are some both for Java and for C++, but selecting from them would probably better fit http://softwarerecs.stackexchange.com/. – Gábor Bakos Jan 07 '15 at 15:01

4 Answers4

4

You could do this...

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;

public class Test {
  public static void main(String[] args) throws Exception{
    ScriptEngineManager mgr = new ScriptEngineManager();
    ScriptEngine engine = mgr.getEngineByName("JavaScript");
    String foo = "2 * 6^( log(123) - sin(7)^cos(2) )";
    System.out.println(engine.eval(foo));
    } 
}

In addition if you want to solve the limits, you could always use an API. You can send the request with the right syntax for that api, which will give you the result you can parse. This is however harder to program and API's are often not free. Another option is calculating limits yourself, I'm not aware of APIs for that or standard Java functions.

If you really want to start from scratch and re-invent the weel I would suggest you build your own eval function. This is a good starting point for that: Java/c++ example.

  • yeah, cool. But what about the limits computation of the example? – ale64bit Jan 07 '15 at 15:06
  • Can't these mathematical computations be done in Java itself? – Sid Jan 07 '15 at 15:35
  • 1
    Java is capable of doing this computations itself, I offer a solution which can be used in Java and I'm aware of the overhead it might cost. http://jeval.sourceforge.net/ is an example... @Sid –  Jan 07 '15 at 15:39
1

This is less of a Java domain question and more of a language parsing problem. The traditional way to approach this is to build a lexer and parser, sometimes in another language, that generates the code in the language you want. This way you separate the parsing concerns from the actual "client" program concerns.

This can be easier, in the long run, than trying to write what is going to be a pretty complicated regular expression state machine that will be hard to prove is correct in all cases. An infix math parser/processor is interesting enough that having a "little language" version of the rules and definitions makes it a lot easier to prove your program is correct.

In Java you might want to consider ANTLR to generate the parser, though I admit I have never had to use it. But my understanding is that ANTLR is familiar enough if you have used Lex & Yacc.

[UPDATE]

I don't know if infix is a hard requirement, but parsing complex math using a stack and postfix operations can be much easier to implement if you don't want to generate a parser. As an added bonus, this allows you to do math like Yoda.

  • You can't parse a Chomsky type-2 grammar with a finite state machine anyway. – laune Jan 07 '15 at 15:10
  • There you go; I wasn't even aware there was an actual limitation other than it would be messy and hard to validate. –  Jan 07 '15 at 15:18
1

If your expressions are not very complex, I think this answer will guide you in the right way:

Built-in method for evaluating math expressions in Java

If your expressions are rather sophisticated, using limits as in your example, I advice you to take a look at the Dragon Book. It should be easier to implement an easy expression parser and use some strong math library below.

Community
  • 1
  • 1
ale64bit
  • 6,232
  • 3
  • 24
  • 44
1

In general, what you need is called a computer algebra system. I don't know what requirements you have but there are at least 2 general ways to go about it.

(1) link your program to a library to do the algebraic stuff. For C++ you can try Yacas and for Python you can try Sympy. Dunno about Java.

(2) write your program separately and talk to a CAS via a socket. In that case the CAS could be anything, e.g., Maxima, Sage, etc etc. A socket interface is maybe less work than you might think -- it is certainly much, much less work than reimplementing CAS functions.

My advice, without knowing your requirements, is to write your program in Python and use Sympy.

Robert Dodier
  • 16,905
  • 2
  • 31
  • 48