• Subject: Re: Currency representation in Lua
• From: Diogo Mildenberger <diogo.milde@...>
• Date: Tue, 6 Sep 2016 09:02:50 -0300

2016-09-04 22:27 GMT-03:00 Doug Currie :
On Sun, Sep 4, 2016 at 8:20 PM, Diogo Mildenberger wrote:

Has someone any experience to share about implementing a system that deals with currency values? I have already been bitten by the problems described in http://floating-point-gui.de/ and I want to find a better way.

The two common approaches are fixed point, as you mentioned, and General Decimal Arithmetic, which is basically base-10 floating point. See: http://speleotrove.com/decimal/

Ten years ago I made a Lua binding for IBM's General Decimal Arithmetic library decNumber called ldecNumber

It does what you need, but is stuck at Lua 5.1. It depends on some Lua 5.1 features that were removed in 5.2, and would be a bit of work to redo. There have also been some updates to decNumber that ought to be incorporated if ldecNumber is updated. If you work on the library you might consider using decQuad (decimal128) if you can get by with 34 digits of precision; the present version of ldecNumber uses arbitrary precision decNumber set to 69 digits of precision.

I spent yesterday taking a look at docs from Doug Currie's suggestion, (l)decNumber, and your other suggestions, and learnt a bit more about the problem.

To clarify, yes, as of now, an integer-based solution would suffice, but I wanted to know if there were other options to keep me from implementing yet another poor man's fixed-point library. Glad to know there are options like decNumber, and I also found out about _javascript_ libraries [1] that implement something similar to Java's BigDecimal (unsure if easy to port to Lua, but a starting point).

Answering Matthias about context: It is currently a simple pure-Lua 5.1 application (in x86) for stock trading analysis that deals with Brazilian Real, possibly the occasional US Dollar, so not much "cents variety". My major problem is really "Why don't my numbers add up?" and I had a primitive understanding of what was going on, even have a half-baked solution, but want better. While searching the web, I saw several mentions about "just using integers" and "it's bad to use integers, use a robust decimal arithmetic solution", so I wanted to know from you what options did you know or have tried.
As for rounding, so far I am going with "Round half to even" aka "Bankers' Rounding".

Now I am a little concerned about performance, given that whatever the option is, it is going to be at the very core of the calculations, but will get to try options before jumping to action. I guess the one with most performance would be (l)decNumber (as it is {ANSI} C -- as far as I understood, no hardware support for decimal floating-point in x86).

Diogo

PS.: I consider this yet another example of the "Law of Leaky Abstractions" (http://www.joelonsoftware.com/articles/LeakyAbstractions.html), even my numbers are "not in Kansas anymore"... :P

[1] https://github.com/MikeMcl/big.js/ among others.