2

I am trying to make a small tool that transfers a math equation to a Java BigDecimal line.

for example:

A + B * C => A.add(B.multiply(C))
A / B + C => A.divide(B).add(C)

Things are getting nasty with brackets.

A - (B + C) / D => A.substract(B.add(C).divide(D))
A - (B * (C + D)) => A.substract(B.multiply(C.add(D)))

My approach is to do it recursively. for example: A + B * C

1. convert( A + B * C ) 
2. A.add( convert (B * C) )
3. A.add(B.multiply(C))

Math Symbols that supports: + - * / % ( )

I was wondering if there is a better way to handle this.

Is there a name for this kind of issue is it? Compiler? (Sorry if it is not, I have never done any work with compiler.) Thanks in advance.

Anew
  • 5,175
  • 1
  • 24
  • 36
Xin
  • 737
  • 3
  • 10
  • 27
  • You are writing a very basic compiler or interpreter. You could google these two words to find some helpful information. – Code-Apprentice Feb 08 '13 at 01:31
  • Also look up grammar parsers. – Antimony Feb 08 '13 at 01:32
  • Pretty much what you want to do is make a parse tree and then traverse the tree with depth first search. Your lowest nodes would have the highest precedence. As others have said, this is very similar to (certain steps of) compiler design. – adchilds Feb 08 '13 at 01:38
  • If your main goal is to evaluate the expressions take a look at: http://stackoverflow.com/questions/7258538/free-java-library-for-evaluating-math-expressions – Anthony Accioly Feb 08 '13 at 01:38
  • Thanks for the replies. :) I guess I need to dig into it a bit more. – Xin Feb 08 '13 at 02:11

2 Answers2

2

You may want to look at a recursive descent parser, illustrated here for double values. The change to BigDecimal is straightforward, but you may have to scale back on the named functions.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
1

why not use Groovy? It directly supports nicer syntax for big decimal arithmetic.

BigDecimal a = ...;
BigDecimal b = ...;
BigDecimal c = ...;
Binding binding = new Binding();
binding.setVariable("A", a);
binding.setVariable("B", b);
binding.setVariable("C", c);
GroovyShell shell = new GroovyShell(binding);

BigDecimal value = (BigDecimal) shell.evaluate("a+b*c");

Groovy also has a direct literal syntax for big decimals as well if you need it;

A = 2G
B = 4G
C = 8G

If your primary goal is simply to input expressions and evaluate them, this is a nice simple approach. If you're trying to generate code, that's a different story.

Matt
  • 11,523
  • 2
  • 23
  • 33
  • ps: http://groovy.codehaus.org/Groovy+Math you'll get the power operator too, and type coercion if you need it. – Matt Feb 08 '13 at 02:55