Horse arses, thumbs and data design of GnuCash — HandsOnMoney Blog
June 6, 2026 • Author: Vitalik
Horse arse set the standard for railways. Spanish traders set it for GnuCash database design.
TLDR: Spanish traders in the 1600s did not want to count their thumbs, which influenced GnuCash's database design choices in 1997.<br>Much like a horse's arse set the standard for railways. How seemingly odd design turns out to be a genius solution that serves people pretty well.
It's one of those nights. A cup of hot coffee is on the table. I'm implementing a commodities support in HandsOnMoney which looks absolutely trivial on the surface, but is quite deep in reality. After all, what can be simpler than currency - there are dollars and cents. What can be simpler than storing a number and calculating totals?
Wait for it. There are multiple layers in this…
Layer one. Cultural.
There is not always 100 cents in a dollar. Well, there is. But other currencies may have no "cents" or have a thousand "cents". Those "cents" are generally called "minor units".
Here are a few concrete examples:
Japanese Yen has no minor units (due to post-WWII inflation)
The Kuwaiti Dinar has a thousand minor units (this allows the country to use smaller increments of value and maintain precise pricing for trade)
And Bitcoin has 100 million Satoshis!
But wait for it. There are even historical currency- real de a ocho that could be divided into 8 pieces! So 1/8th of a coin was the smallest indivisible unit!
Which brings us to the next layer - how in the world do we store it?
Layer two. Software.
Computers are not good with fractions. There are abstractions: float and double types.<br>But they are approximations rather than real fractional numbers.<br>The late 90s and early 2000s brought us decimal, which is a much better type;<br>however, it was likely not available when GnuCash was released.
There is a lot written about it. Usually, developers use a double numeric type to record and store the floating-point numbers. But this solution for recording floating-point numbers does not play well with money.
For example, it is possible that.
1.03 - 0.42 = 0.6100000000000001
Which seems like a trivial rounding error. But over a large number of transactions, the rounding error will accumulate, and you'll eventually see a weird account balance.
In addition, money has a fixed precision and specific rounding rules. So software engineers stepped on this landmine so many times that they developed a common pattern - Money. Which, in a nutshell, is just storing minor units in whole numbers since computers are pretty good with them. So instead of recording $5.23, the money is stored as 523 cents.
Problem solved? As you'd expect - no.
Layer three. Historical.
It's not about money. Well, it is. But it is not only about money. It's also about commodities. In a nutshell, money is a commodity. People trade various commodities - currencies, stocks, and funds.
This generalization needs us to go back in the past. And…
Party like it's 1998
It's 1998. The year of the first release of GnuCash (xacc at that time). Dotcom money is pouring from the firehose, party everywhere…
But the most important thing - NYSE quotes are not decimal. They are fractional!
GnuCash was released before the decimalization of US exchanges was completed in 2001.
Why? Get back into the time machine and …
… trade like it's the 16th century
When the NYSE launched over 200 years ago, it adopted the Spanish trading system from the 1600s, based on fractions because traders counted gold doubloons on their fingers, skipping their thumbs. That's why the smallest stock increment was 1/8 of a dollar. Not a technical decision. A thumb decision. (source - Investopedia)
Okay, enough of counting fingers in the 16th century. Let's get back to 2026.
Layer four. Data Engineering.
In 2026, everything is traded in decimals. We are counting fingers and thumbs.
Is GnuCash's design decision to store fractions an artifact from the past?
It already caused a bug
The register in 2.7.8 displays fractional price for commodity accounts. This is a bit confusing to look at as my brain is too slow process the division of i.e. 1250 with 2449. See https://imgur.com/SA3Kkbh https://bugzilla.gnome.org/show_bug.cgi?id=794755
Mostly yes. GnuCash is full of little quirks from the past (it still supports Italian Lira, which was replaced with Euro in 1999!).
But this seemingly outdated design decision to store fractions works extremely well in a modern world.
Consider this example: if I bought 1 Bitcoin in 2011 for 90 cents. In my GnuCash book, I recorded
Account<br>Debit<br>Credit
2011<br>Checking Account
9/10 cents
Bitcoins<br>1 Bitcoin
Now in 2026. I can sell a fraction of my holdings and price it in Bitcoin's minor unit - Satoshi.
I can easily flip the Bitcoin precision in the commodities editor from 1 to 100,000,000, and GnuCash will still calculate the balance without any issues.
For example, here I'm selling...