Search code examples
javafloating-pointprecisioncurrency

Monetary precision in Java (not BigDecimal)


We know that using float or double is not the option where correct precision is necessary, and we know BigDecimal serves that purpose but we also know that it's about 100 times slower than regular primitive operations.

Now what do we do if speed is critical for us and we do really need precision?

I tried to store value of currency in slowest unit and store its conversion like 1 BTC = 100000000 satoshi but after few experiments its clear that you simply won't be able to store 100BTC in long, exceeds max possible value. Yes there is an option to sacrifice precision like storing microBTC and so on, but the problem is more global, how we design such thing with primitives?


Solution

  • As D.E.Knuth's has amply documented in his vol 2 of "The Art of Computer Programming" implementing arithmetic with arbitrary precision isn't "black art" - see the chapter "Seminumerical Algorithms". I've been through that, following the necessities of implementing COBOL computationals (so: not only integers).

    Also, making a workalike of BigInteger or BigDecimal without recreating an object for each new op result is an option. Yes, it means work, but if you really think you need it...

    I have found that BigInteger isn't so slow as far as the arithmetic is concerned. What really killed using that for me was the necessity to convert between binary and decimal (array of decimal digits) frequently.