fixed point arithmetics in java with fast performance

Viewed 17710

I need to represent some numbers in Java with perfect precision and fixed number of decimal points after decimal point; after that decimal point, I don't care. (More concretely - money and percentages.)

I used Java's own BigDecimal now, but I found out, that it's really slow and it starts to show in my application.

So I want to solve it with a "regular" integers and a fixed-point arithmetics (long integers have big enough precision for my purposes).

Now, I would think that I am not the first one who has this kind of problem and there would be already a library for that, that already has multiplication/division implemented - but it seems that it isn't.

Now, I very probably can write it myself (and I probably will), but really, am I really the first person that needs this? Isn't there already some library for that?

4 Answers

Although this is not exactly what you are asking about, this can speed up your app without leaving BigDecimal:

Since Java 8, this is solved by BigDecimal itself. A new class MathContext was added and limits the precision to which the operations are calculated.

var num = new BigDecimal("1234.56780", new MathContext(10, RoundingMode.DOWN));

The catch is that the precision 10 does not apply to digits after decimal point. It applies to the number of significant digits. For 1234.50, 6 is needed.
For 1_500_000_000.100, 13 is needed to keep the number as is.
So the precision might suffer when you had a precision of 10 and counted billions of Czech Korunas.
Still, a precision of, say, 1000, is way faster than unlimited precision (which is I think the default).

This can also be applied to the individual operations:

BigDecimal n = new BigDecimal("0.12345");
n = n.pow(2, new MathContext(1000, RoundingMode.DOWN));
n = n.pow(2, new MathContext(1000, RoundingMode.DOWN));
n = n.pow(2, new MathContext(1000, RoundingMode.DOWN));
n = n.pow(2, new MathContext(1000, RoundingMode.DOWN));
Related