The data type is floating, which is a NO GO #118

Closed
kuerzn opened this Issue May 31, 2013 · 8 comments

Projects

None yet

3 participants

@kuerzn
kuerzn commented May 31, 2013

I think this is a no brainer: You cannot use floating point in accounting. Either arbitrary or fixed precision. but definetly EXACT ARITHMETIC.

see also
http://stackoverflow.com/questions/61872/use-float-or-decimal-for-accounting-application-dollar-amount

@massysett
Contributor

https://groups.google.com/forum/?fromgroups#!msg/hledger/8-T8CVNCWCU/p1PlJQrZYFwJ

though unfortunately I never took Simon up on his offer to work on this...

@simonmichael
Owner

Pull requests and benchmark results welcome!

@simonmichael
Owner

Starting out this way was a useful expedient, and since then other things have always been higher priority. If you give me a real example of a problem this causes in your actual usage, that'll help raise the priority on it. We've only had one such in hledger's history (and we took care of it.)

@massysett
Contributor

I've written a library, named deka, for decimal arithmetic. It's a binding to mpdecimal, a C library that Python uses for decimal arithmetic.

https://hackage.haskell.org/package/deka

mpdecimal is thoroughly tested. deka is also thoroughly tested; though deka does not do arithmetic itself, the tests help ensure there's no bug in the binding code (e.g. transposed arguments.)

@simonmichael
Owner

Thanks for the pointer, although hledger avoids depending on C libraries as far as possible.

@massysett
Contributor

In that case you want this:

http://hackage.haskell.org/package/Decimal

although it's not much harder to do decimal arithmetic using Integer. The problem is that getting division and rounding right is a nightmare. However, ledger and hledger both rely heavily on division and rounding to get commodity treatment right. Lack of attention to this has caused problems:

https://groups.google.com/forum/#!searchin/ledger-cli/rounding/ledger-cli/m-TgILbfrwA/i8m6A697WWsJ

Given the importance of division and rounding to this data model, should anybody go down the road of getting proper integer-based arithmetic in hledger I think she will have a much easier time implementing it properly if she uses a library that has already paid attention to the numerous issues involved in proper division and rounding. Even a quick look at the General Decimal Arithmetic Specification and mpdecimal shows that this is not something that is easy to do. Leave it to somebody who has already thought about the numerous issues and methods involved. Currently that would mean using a C library. deka is Haskell so it keeps the C nastiness away from you. However, given the difficulty of this problem I doubt anyone is going to implement a pure Haskell library for properly rounded decimal arithmetic, especially when 1) that's why Haskell has an FFI, and 2) there is already more than one thoroughly tested, speedy C solution to this problem.

Since current hledger developers have no interest in this problem (and I'm not saying they should; I understand why most people would not care about this) I don't expect my comments here to have any immediate effect; I just leave them for future reference. Solving this problem correctly will be most easily done if you use a library that has given thought to the problems involved. Those are written in C. If you don't want to use a C library, honestly I would just recommend sticking with Double and the pile of hacks that have been built to make this improper data type work in hledger (again, not a negative criticism, I understand why this choice was made; however, functions like isReallyZeroMixedAmountCost are hacks that would not be necessary with the use of proper integer arithmetic.)

@simonmichael
Owner

It's wrong to say I'm not interested in the problem - I clearly am, but as always there are tradeoffs being managed (performance, cross-platform installability, maintainability, priority relative to other hledger work, my time, contributor time..) This info will be very useful, thanks.

PS to be clear, non-floating point arithmetic has always been a goal for hledger and will happen sooner or later.

@simonmichael simonmichael added a commit that closed this issue Oct 18, 2014
@simonmichael switch to Decimal for representing quantities (closes #118)
hledger has represented quantities with floating point (Double) until
now.  While this has been working fine in practice, the time has come to
upgrade our number representation to something more principled: Decimal,
for now. As a bonus, this brings a ~30% speed boost to most reports.

We'll keep the old representation(s) around for a while, selectable via
hledger-lib cabal flag, for research/testing/benchmarking purposes. To
build with the old Double representation: cabal install -fdouble
hledger-lib hledger hledger-web
3b70362
@simonmichael simonmichael added this to the 0.24 milestone Oct 18, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment