reproducible, & possibly configurable rounding

Josh Berkus josh at agliodbs.com
Thu May 8 13:21:17 EDT 2014


(including the list in my reply, I hope you don't mind)

On 05/07/2014 06:44 PM, tripun goel wrote:
> Hi Josh,
> 
> 
> On Thu, May 8, 2014 at 5:21 AM, Josh Berkus <josh at agliodbs.com> wrote:
> 
>> On 05/07/2014 04:01 PM, Bradley M. Kuhn wrote:
>>> I originally characterized Tripun's project as a "implement fixed point
>>> arithmetic"; which I naïvely thought was the "only way to handle the
>>> rounding problem properly".  I've since been educated: there is more
>>> than one way to get this done right, and I think the way we're leaning
>>> is to clearly document options, why we picked the option we did, and
>>> (ideally) make Ledger-CLI more configurable on this point by the user.
>>
>> ???
>>
>> Ledger is written in Python, which has the decimal type for fixed-point
>> arithmatic.  You shouldn't have to implement that.
>>
> 
> Originally it is written in C++ and uses MPFR library for handling
> rounding. We are trying to fix it once and for all.

:-(

Well, if you're doing all python code now, the solution is simple; use
decimal.decimal.  Fixed-decimal-point numbers are your friend here.
When I do the PostgreSQL backend eventually, that will use NUMERIC, not
FLOAT, for the same reason.

> 
> 
>>
>> I don't know of a non-cpu intensive method for handling splits, though.
>>  Here's the basic issue:
>>
>> Imagine that a particular kind of revenue gets automatically split
>> evenly between 4 earmarks.  Then you receive $14.21 in that account.
>> How do you split it so that you don't lose a penny?
>>
>> When I had to implement it before, my routine looked like this:
>>
>> - split amount naively, rounding to two decimals (for USD)
>> - compare that against the original amount
>> - figure out the number of "lost" pennies
>> - reassign those pennies to the splits, based on random selection with
>> the probability of each penny being assigned to a split as the % of that
>> split, with no duplicates.
>>
>> I can write some primitive python code up for this process if it'll help.
>>
>> Interesting case though, Its a good case to check whether ledger does it
> properly or not. We should think of more such cases.

Well, I don't know if my solution is "right", although it did pass
muster with a professional auditor.

I've seen other solutions.  For example, one alternative solution is
that your storage system actually keeps an extra decimal point (for USD,
0.000), and doesn't round that off until you have to output something.

-- 
Josh Berkus
PostgreSQL Experts Inc.
http://pgexperts.com


More information about the npo-accounting mailing list