lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> glen@worstell.com wrote:
> [...]
>> You will not have accuracy problems until you have a great many
>> transactions ...
>
> It depends very much what you do. The errors show up immediately when
> rounding edge cases.
>
> 70 cents + 5% == 0.70 * 1.05 = 0.735, which should round up to 0.74, but:
> ...

No. There are 3 different common financial types of rounding: Banker's
rounding, which you describe, round up, used on your tax returns as the
IRS requires it, and round down. I suppose one could say that when using
floating point (not as integers) for financial calculations there is a
fourth method which goes up or down depending on the number, as the least
significant bits (which the user never sees when using doubles for
financial calculations) will determine which way it goes. In other words,
the exact double precision representation of an amount such as x.5 may be
a tiny bit above x.5 or a tiny bit below, so the rounding of x.5 may go
either way, depending on x.

Still, you bring up a good point: if you use either of my two suggested
methods for financial calculations, and if you need to do rounding, you
must be careful about how this is done. It may be necessary to write a
function to do rounding in order to get the result you desire.

In my particular application I have done this analysis. It turns out that
I only need to round in one situation, and in that situation it does not
matter which of the three (or, rather, four) types I use, so I use the 4th
method as that is the easiest.

>
> There are other problems, too; consider 1.0 % 0.1. The result should be
> 0, right? Try it:
>
> print(1.0 % 0.1) -> "0.1"

wow! I learn something every day. I did not know that Lua has a %
(modulus) operator. Was that added in the latest version? I have only the
version described in the original Programming in Lua book, and it does not
mention %. I'll need to make sure that it works as desired on integers
(that is, doubles that are whole numbers) and if it does I can put it to
good use in my financial application.

To elaborate: when coding integers as doubles, the operators +,-,* work
exactly as they should, and give exact results. Lua itself depends on this
behavior. The % operator may or may not give exact results (I suspect that
it does) depending on how it is coded. the / operator, of course, can not
give exact results, in general. Lisp has rationals, which are exact, but
that is another whole different animal (not nice and small, like Lua!)

Still, on my system (Windows XP, Lua 5.1.3), the code above yields a
number, not a string, and the number is zero, exactly.

>...

> Here's a good explanation, although it is in Fortran:
>
> http://h71000.www7.hp.com/wizard/wiz_8846.html
>

Yes, anyone doing this sort of stuff needs to understand how floating
point actually works (which I do). The reference does not discuss rounding
in financial applications, though. A better reference might be:

http://www2.hursley.ibm.com/decimal/decifaq1.html#rounding

For completeness I should mention that there are several other types of
rounding besides the 4 I mentioned.

Glen.

PS - Were I writing a financial app requiring representation of huge
numbers like the national debt, I'd just use C# (or Mono), which has a
decimal type.