I write currency trading applications for living, so I have to work with monetary values (it\'s a shame that Java still doesn\'t have decimal float type and has nothing to s
1/b is not exactly representable with BigDecimal either. See the API docs to work out how the result is rounded.
It shouldn't be too difficult to write your own fixed decimal class based around a long field or two. I don't know any appropriate off the shelf libraries.
I know that I'm posting under very old topic, but this was the first topic found by google. Consider moving your calculations to the database from which you probably are taking the data for processing. Also I agree with Gareth Davis who wrote:
. In most bog standard webapps the overhead of jdbc access and accessing other network resources swamps any benefit of having really quick math.
In most cases wrong queries have higher impact on performance than math library.
You might want to move to fixed point math. Just searching for some libraries right now. on sourceforge fixed-point I haven't looked at this in depth yet. beartonics
Did you test with org.jscience.economics.money? since that has assured accuracy. The fixed point will only be as accurate as the # of bits assigned to each piece, but is fast.
Commons Math - The Apache Commons Mathematics Library
http://mvnrepository.com/artifact/org.apache.commons/commons-math3/3.2
According to my own benchmarking for my specific use case it's 10 - 20x slower than double (much better than 1000x) - basically for addition / multiplication. After benchmarking another algorithm which had a sequence of additions followed by an exponentiation the performance decrease was quite a bit worse: 200x - 400x. So it seems pretty fast for + and *, but not exp and log.
Commons Math is a library of lightweight, self-contained mathematics and statistics components addressing the most common problems not available in the Java programming language or Commons Lang.
Note: The API protects the constructors to force a factory pattern while naming the factory DfpField (rather than the somewhat more intuitive DfpFac or DfpFactory). So you have to use
new DfpField(numberOfDigits).newDfp(myNormalNumber)
to instantiate a Dfp, then you can call .multiply
or whatever on this. I thought I'd mention this because it's a bit confusing.
It seems like the simplest solution is to use BigInteger instead of long to implement pesto's solution. If it seems messy it would be easy to write a class that wraps BigInteger to hide the precision adjustment.
Assuming you can work to some arbitrary but known precision (say a billionth of a cent) and have a known maximum value you need handle (a trillion trillion dollars?) you can write a class which stores that value as an integer number of billionths of a cent. You'll need two longs to represent it. That should be maybe ten times as slow as using double; about a hundred times as fast as BigDecimal.
Most of the operations are just performing the operation on each part and renormalizing. Division is slightly more complicated, but not much.
EDIT:In response to the comment. You will need to implement a bitshift operation on your class (easy as along as the multiplier for the high long is a power of two). To do division shift the divisor until it's not quite bigger than the dividend; subtract shifted divisor from dividend and increment the result (with appropriate shift). Repeat.
EDIT AGAIN:You may find BigInteger does what you need here.