round

The round function is not suitable for financial rounding, apparently. Why is that?

Because if you use rounding in financials, your accountant will never talk to you again!

Use integers to calculate in terms of your smallest denomination (pence, cents, whatever), format the results to look like real money (pounds.pence, dollars.cents, whatever). (Bob Clark)


That doesn't sound right - if I calculate loan payments in terms of cents, then that means that one can lose nearly whole cents - if the payment would have come to $1001.01999 (or in other words 100101.999 cents) by using floats, by using integers, I end up with $1001.01 - but the bank is very likely going to be expecting me to pay $1001.02 ...


Phew, big subject - you're right of course, and so am I. Part of the problem is that floats can't represent some numbers accurately. Suppose you multiply two floats together where you'd expect the answer to be $1001.50 but float arithmetic returns $1001.499999... instead. Apply [expr {round()}] to that and you'll get $1001 instead of the expected $1002. This is not a bug in Tcl round(), it's just a consequence of using floats. Floats were designed by and for engineers and scientists, not accountants.

There is a huge IBM FAQ on the subject at [L1 ]. (link goes to an IBM landing page on 2012-06-11)

You might notice that some languages have a special Currency data type for money - Visual Basic springs to mind - now you can see why. I don't believe there's a simple resolution to the problem in Tcl, or in anything based on the C libraries, apart from using integer cents so far as you can, and being very careful indeed everywhere else. You could perhaps look at Tcl's mpexpr package.


In the old days, under IBM MVS basic assembly language (BAL), there used to be a data type called Binary Coded Decimal (BCD) which if I recall correctly were useful for this sort of thing.

Perhaps an extension which implemented such a data type would be of use to Tcl programmers who write financial applications. Anyone out there responsible for such a thing?


There's the beginnings of a Tcl BCD implementation by Gerald Lester in this wiki at Tcl based Packed Decimal Arithmetic, but unfortunately it's not finished and doesn't do division.