Rethinking Numeric and rounding

Wm Tarr wm.tarr at
Tue Jun 3 21:47:09 EDT 2014

On 01/06/2014 21:07, Christian Stimming wrote:

>  From my point of view the problem is still not yet understood completely here.
> IMHO the problem is not too much rounding -- the problem instead is too little
> rounding. What are the exact requirements on the handling of rounding and
> overflow from our application domain? My argument is that our application
> domain of *managing finances* will give us the requirement to do the rounding
> according to normal currency numbers! Instead, our implementation using
> rational numbers tries to be "more precise" than rounding to currency numbers.
I agree with this.  There is no point in precision beyond natural or 
market trade.  If the global market rounds at a number of decimals then 
we should too, I think.

If people are using gnc for enormous fund movements where fractional 
amounts of major currency are important I think they should send this 
project a few units of currency :)

> In effect, this is not more precise but rather more wrong. We must not pretend
> to be more clever than the calculations that happen in reality. Speaking of
> finance calculations, we must not do the calculations with lesser rounding
> than what IFRS or similar authorities will clearly specify. Hence, your
> statement that our "internal representation is always exact" is correct from
> our programmer's point of view, but IMHO it is not true from the application
> requirement point of view (due to missing financial rounding). Your $0.01
> discrepancy is a symptom of exactly that. This doesn't mean our calculation is
> "more correct", it unfortunately just means our calculation is wrong.
The sum is correct, the allocation of the penny must be made.  I think 
Christian and I are saying the same thing, here.  I also think John 
(right or wrong) doesn't want to allocate the penny.

> Here's an example where the missing rounding will lead to wrong results: Let's
> do some currency exchange, say between USD and EUR. Let's assume an exchange
> rate of 1.50 USD = 1.00 EUR (given with normal currency SCU [1] i.e. 2 digits
> after the decimal point here) or almost equivalently an exchange rate of
> 0.6667 EUR/USD (given with more digits after the point). Let's say the user
> wants to enter some transactions where she sold 1 USD with the given rate
> 0.6667. She enters those numbers in the txn dialog: 1.00 USD, rate 0.6667, and
> gnucash will calculate the resulting third number: 0.6667 EUR, but the display
> will show 0.67 EUR due to the currency's SCU. The user presses Ok because the
> resulting 0.67 EUR will match the number on the receipt, i.e. the 0.67 EUR
> were the amount that resulted in reality. However, if the gnucash account
> contains "the exact value" 0.6667 [2] and we don't do the correct rounding of
> this exchange transaction to the currency's SCU, the gnucash account shows
> 0.67 EUR but internally contains a little bit less. Now the user enters a
> second identical transaction: 1.00 USD, rate 0.6667, the displayed EUR value
> is 0.67 which is the amount from reality. The user presses Ok again and she
> has 2 * 0.67 EUR in reality = 1.34 EUR. However, in gnucash, the account
> contains 2 * 0.6667 EUR = 1.3334 EUR, rounded for display to 1.33 EUR. Huh,
> where did that 0.01 EUR go missing?
It doesn't need to be that complicated.  Any recurring sum will produce 
something similar.

The fact is RL transactions don't have indefinite decimals.

> My conclusion: We need to introduce more intentional rounding. Every time when
> the result of a calculation represents a monetary amount that has some known
> SCU (either from the currency or from the account), this amount needs to be
> rounded to exactly those digits. No more, no less. And not only for display,
> but for the real amounts.

> The overflow of the int64 rational numbers is not a problem but inevitable and
> probably completely fine. Any numerical data type must have some restriction
> on its precision sooner or later, as long as our computers have to live with
> finite amounts of memory. Every division and multiplication will increase the
> significant digits of the resulting number. This just says that in computer
> arithmetics there will always be the question of when to do the rounding. We
> can't get around this. So we should better do the rounding according to the
> application domain's requirements, which in our case means the rounding
> happens rather soon. No need to get more significant digits from somewhere.
> The number data type could have been chosen more suitable to our application
> domain (which is what I pointed out by the decimal64 floating point format),
> but the resulting 19 significant digits of gnc_numeric are just fine.
> Did I get something completely wrong here? If we are missing the intentional
> rounding of monetary values, this will be a problem, but the finite precision
> of gnc_numeric will probably not be a problem.

I think, Christian is heading in the right direction.


More information about the gnucash-devel mailing list