[GNC] gnucash_user: rounding errors and significant digits

Jim DeLaHunt list+gnucash at jdlh.com
Mon Aug 21 17:00:05 EDT 2023


Bruce:

Welcome to the gnucash-user email list! Hopefully we can give you some 
useful answers. I will answer based on what I have heard developers say 
on the list, and what I see in my stock transactions in GnuCash, though 
I have not read the relevant GnuCash source code.

On 2023-08-21 10:21, Bruce McCoy via gnucash-user wrote:
> ...Could you please help me comprehend what ishappening in the 
> calculations of gnucash compared with thecalculations of Federated 
> Hermes? FederatedHermes determines the number of shares traded by the 
> currency amountof the trade divided by the price of the shares. For 
> example, onceupon a time they charged me a $15.00 Annual Fiduciary 
> Administrationfee. The share price was $6.26. To meet the fee they 
> sold 2.396shares and recorded it on their statement as -2.396 shares, 
> accurateto 1/1,000 of a share, for the transaction.....

It sounds like they charged you 2.396 shares to fulfil an obligation for 
$15.00. They used the price of $6.26 to arrive at the amount of 2.396 
shares, but it is not a fundamental part of the transaction. This is 
important to how GnuCash records such transactions.

Logically, $value = $price/share * #shares, and this should be precise 
equality. But is possible for a brokerage statement to report values 
which do not have precise equality. It sounds like Federated Hermes 
reported $15.00 = $6.26 * 2.396, but the actual $value of this $price 
and #shares is $14.99896, a difference of $0.00104.

GnuCash takes the position that price is approximate and transient, but 
currency received and paid, and shares received and issued, are exact 
and persistent. Thus a GnuCash securities transaction stores the number 
of shares and the currency value of the transaction, and derives the 
price as $value/#shares. It stores the price as a rational number, a 
ratio between numerator and denominator (i.e., a fraction). Thus it will 
exactly satisfy the logical equation.

In your example, I expect GnuCash stored the price as , simplified to 
3750/599 $/share.

> As we see below thenumber of shares they reported was truncated from 
> the more accuratefigure given below. AnnualFiduciary Administrative 
> Fee of $15.00/Share price of $6.26 =2.3961661341853035143769968 
> 05111821086261980830670926517571884984025559105431309904153354632587859425shares 
> traded. Ingnucash, entering the fee of $15 and the number of shares as 
> 2.396,results in gnucash reducing the shares in the fund by 2.4, 
> changingthe fund and expense accounts by $15.02, and setting the trade 
> priceat $6.2583. Gnucashunderestimates the trade price by 
> (1-(6.2583/6.26))*100 = 0.02715 %. Gnucashcould use a longer fraction 
> to generate a more accurate share price. This only requires that the 
> fraction have more significant digits. If gnucash multiplied the 
> $15.00 fee by2.3961661341853035143769968051118 
> 21086261980830670926517571884984025559105431309904153354632587859425shares, 
> won't the result be a share price of $6.26.

Please rethink this paragraph, treating the currency amount and number 
of shares in the transaction as fundamental, and the price as a 
byproduct. It would be something like, Annual Fiduciary Administrative 
Fee of $15.00, #shares = 2.396, price = 15000/2396 = 3750/599 $/share. 
In decimal terms, this is about $6.26043405676127/share. You might 
describe it as, "the transaction price they reported was rounded from 
the more accurate 3750/599".

I am interested by your statement, "results in gnucash reducing the 
shares in the fund by 2.4". GnuCash is capable of storing share counts 
to three decimal places. However, a setting in the Account window for 
the security controls the number of decimal places GnuCash uses for that 
security. See the Tutorial and Concepts Guide, 9.4.1. *Setup Accounts 
for Stocks and Mutual 
Funds*<https://www.gnucash.org/docs/v5/C/gnucash-guide/invest-setup1.html#invest-setup-stockaccounts2>. 
See also Figure 9.8. *The “New Security” Window*, on that page.

For your security, what is the value for "fraction traded" in the 
security window? It should be 1/1000 or smaller. What is the value for 
"Smallest Fraction" in that dialogue box? It should be "Commodity Value".

> Mutualfunds seem to treat both the amount of the local currency 
> tenderedand the price per share as decimal numbers of high precision 
> e.g.$15.0000000000000000000 or $6.260000000000000000000000. They seem 
> toconsider the number of shares traded as an approximation. Of 
> coursethey add and subtract fractional numbers of shares. Where do we 
> seethem dividing the transaction cost by the number of shares, 
> includingfractional shares, to calculate the the price per share? 
> Inevery mutual fund statement I have seen, the prices and the 
> numbersof shares always agree from month to month....

You just gave an example of a transaction where the price and number of 
shares does not agree with the currency value of the transaction: $6.26 
* 2.396 = $14.99896, not the stated value $15.00.

I would characterise this as, mutual funds seem to treat the amount of 
the local currency tendered and the number of shares as decimal numbers 
of exact precision, and the price as an approximation.  Certainly, it 
will help you understand GnuCash's recording of these transactions if 
you think of it that way.

> ...Why do we not ...incorporat[e] more significant digits in the 
> calculations? InEdit > Preferences > Numbers, Date, Time > Numbers 
> >Force Prices to display as decimals, the maximum number of 
> decimalplaces one can display is only 8 (eight). If this is close to 
> thenumber of significant digits gnucash is currently using, could it 
> bethat we might consider using, instead of, say, double 
> binaryfloating-point method, a decimal floating-point arithmetic...

Note that you are talking about increasing the actual precision of 
numbers used in calculation, but the spreadsheet preferences setting you 
mention controls only the _display_ of numbers, not the actual precision 
of the numbers.

GnuCash stores the price as rational numbers, which can have precisely 
the correct value. Floating-point numbers, no matter the precision, will 
always be approximations. A floating-point number cannot exactly store 
the value of one-third (1/3), but a rational number can.

> ...Whydo we not avoid rounding errors? Why do we not enjoy the 
> accuracyand precision that everyone else can? Well, we can increase 
> theprecision of our calculations by increasing the number of 
> significantdigits in the decimal representations of our numerical 
> data. Bruce

 From what you have presented, it looks to me like GnuCash has 
sufficient precision to record your transactions. I suggest that path 
forward is 1. to think differently about what is fundamental in these 
transactions, and 2. to be sure that you have the security's "fraction 
traded" set correctly in your books.

Does that help?

Best regards,
     —Jim DeLaHunt



More information about the gnucash-user mailing list