Big Freaking Numbers
During the last few weeks I've been working on a workaround on one of the limitations of Java that I personally find extremely annoying. If you've ever done some serious BigDecimal calculations in Java (like the ones required in the financial industry) then you will probably have experienced the pain that comes with it. Turn a simple calculation into BigDecimal operations, and you have effectively obfuscated your code in such a way that it becomes impossible to understand it afterwards.
I decided that anything would be better than just handcoding the BigDecimal operation sequences, so I figured that it should be possible to have some kind of tool that turns a simple expression into the required BigDecimal operations. Building an expression interpreter like this actually wasn't really that hard at all, with a little help of SableCC and a Maven SableCC Plugin I created before.
So this is what a simple BigDecimal calculation looked before:
/**
* Calculates (a / 20) * (b + 123.90)
*/
public void calculateIt(BigDecimal a, BigDecimal b) {
BigDecimal v1 = new BigDecimal("123.90");
BigDecimal v2 = v.add(b);
BigDecimal v3 = new BigDecimal("20");
BigDecimal v4 = a.divide(v3, BigDecimal.ROUND_HALV_EVEN);
BigDecimal v5 = v2.multiply(v4);
return v5;
}
... and this is how you would do it using the APIs of project BigNumbers:
/**
* Calculates (a / 20) * (b + 123.90)
*/
public void calculateIt(BigDecimal a, BigDecimal b) {
ExpressionBuilder builder = ....;
Expression expression = builder.create("(a / 20) * (b + 123.90)");
VariableMap map = new VariableMap();
return expression.evaluate(map.assign(a, "a").assign(b, "b"));
}
Now, the number of lines of code actually didn't really change that much at all, but at least it stays constant (it won't grow with every new operator in your expression) and moreover: most of the code is just boilerplate code that could in fact be inserted based on attributes and IoC mechanisms. More about that in the future.
The other thing to note is that I left out the construction of an ExpressionBuilder instance. That is because there are multiple implementations of this ExpressionBuilder. At this stage, project BigNumbers provides an ExpressionBuilder that basically traverses the expression AST for every evaluation, and an implementation that turns the entire expression into bytecode and loads the bytecode on the fly. I'll also blog a little bit more about that in the near future.
You can download a first version of project BigNumbers from SourceForge.
( Jul 21 2005, 04:15:33 PM CEST ) Permalink Comments [0]

