Rounding in the price db.

Geert Janssens geert.gnucash at kobaltwit.be
Fri Aug 28 09:43:26 EDT 2015


On Friday 28 August 2015 08:55:53 John Ralls wrote:
> I’ve pushed a feature branch, single-price, to my Github repo
> (https://github.com/jralls/gnucash) which covers most of what we’ve
> discussed here. I’m still wrestling with the math of how to sensibly
> handle rounding itself, so what’s there still uses the hard-coded
> 10^6 denom. The branch is from maint because I’d like to put these
> changes in 2.6.8.
> 
> The actual changes are explained in the commit notes. In my limited
> testing it appears to work and to provide stability when doing
> multiple transactions with the same exchange rate. Please test some
> more; I’m sure I didn’t think of every possible variation.
> 
Hi John,

Thanks for your work on this.

>From my first tests and reading the code I have the following observations:

- Let me start with a nit-pick: while reading through the commits I got confused by the return 
values of check_account and check_edit. They return TRUE if the check fails (that is when 
anything is not ok to continue with a transfer). From a distance that seems backwards. I usually 
expect a check function to return TRUE if all checks pass correctly.

- Next I created a vendor bill, posted it and then paid it in a foreign currency. This also pops up 
the transfer dialog. I entered a price and continued. This added the price to the db (as 
expected). Next I remove the payment transaction (from the bank account in the foreign 
currency) and issue a new payment via the payment dialog, again in the same foreign currency. 
This time however, I enter a to amount directly (ensuring it would result in a completely 
different price). Check the price db and note the existing price hasn't changed.

- The currencies I was playing with are € (from currency) and HKD (to currency). Before your 
changes my price db listed a HKD security EUR currency. On your branch the code now adds a 
EUR security in HKD currency. That change is fine in itself. I prefer your normalized way to store 
(currency) exchange rates in the db. The issue with this however is that F::Q won't return an 
exchange rate for the new price, while it did (and still does) for the old one.

> As for the math, here’s the conundrum: I proposed earlier to base the
> rounding on what would make a 1 scu change in the “to” commodity. The
> problems with that idea are that it depends entirely on the amount in
> the “from” commodity and that prices are often quoted in fractions of
> a scu. For example, the Wall Street Journal website quotes the Yen at
> 120.98 to the USD. The Yen’s scu is 1, and the change in the rate to
> make a 1¥ change in the value is different if the USD amount is $10
> from what it would be if the amount was $1000. Carry that to its
> illogical conclusion and we need infinite precision, and that’s
> ignoring the fact that we need infinite precision to exactly
> represent a lot of rational fractions, but since all the real money
> systems use decimal math nowadays that’s not really germane.
> 
> So I have a new proposal: If the commodities are both currencies,
> store exchange rates in the direction where the rate > 1, set the
> denominator to 1000, and round-half-up. The price retrieval code
> already checks in both directions. If only one of the commodities is
> a currency then it’s a price and we store it in the currency with the
> denominator = the currency’s scu * 10000.
> 
See above: the check in both directions is not reliable/borked.

> That leaves commodity-commodity prices. The most common example in
> modern life is stock-for-stock exchanges resulting from mergers or
> spin-offs. These tend to be one-offs, so no rounding required. Barter
> exchange, where one exchanges one commodity for another (e.g. two
> bushels of corn for a cow), is similarly fractional rather than
> decimal, so again not rounding is appropriate. The third case is the
> problem: Bitcoin and similar pseudo-currencies. For maint I think
> we’re going to have to leave those prices unrounded as well, but
> perhaps for master we should consider creating a separate commodity
> category so that users can create commodities that GnuCash treats as
> currencies.
> 
That looks like a very sensible proposal to me.

Regards,
Geert


More information about the gnucash-devel mailing list