From 43bcedea1955e711a10389a6b8b213be35c19e62 Mon Sep 17 00:00:00 2001 From: xuhcc Date: Tue, 1 Oct 2024 12:52:11 +0400 Subject: [PATCH] Deployed b685439 with MkDocs version: 1.2.4 --- ...rison_of_beancount_and_ledger_hledger.html | 4 +- api_reference/beancount.core.html | 10 +- api_reference/beancount.parser.html | 8 +- api_reference/beancount.tools.html | 2 +- api_reference/beancount.utils.html | 2 +- external_contributions.html | 1 + importing_external_data.html | 13 ++- index.html | 2 +- search/search_index.json | 2 +- sitemap.xml | 96 +++++++++--------- sitemap.xml.gz | Bin 768 -> 768 bytes tutorial_example.html | 8 +- 12 files changed, 75 insertions(+), 73 deletions(-) diff --git a/a_comparison_of_beancount_and_ledger_hledger.html b/a_comparison_of_beancount_and_ledger_hledger.html index e17d776..b32dad2 100644 --- a/a_comparison_of_beancount_and_ledger_hledger.html +++ b/a_comparison_of_beancount_and_ledger_hledger.html @@ -359,7 +359,7 @@

Numbers and Precision of Operations

Beancount, Ledger and HLedger all differ in how they represent their numbers internally, and in how they handle the precision of balance checks for a transaction’s postings.

First, about how number are represented: Ledger uses rational numbers in an attempt to maintain the full precision of numbers resulting from mathematical operations. This works, but I believe this is perhaps not the most appropriate choice. The great majority of the cases where operations occur involve the conversion from a number of units and a price or a cost to the total value of an account’s posted change (e.g., units x cost = total cost). Our task in representing transactional information is the replication of operations that take place mostly in institutions. These operations always involve the rounding of numbers for units and currencies (banks do apply stochastic rounding), and the correct numbers to be used from the perspective of these institutions, and from the perspective of the government, are indeed the rounded numbers themselves. It is a not a question of mathematical purity, but one of practicality, and our system should do the same that banks do. Therefore, I think that we should always post the rounded numbers to accounts. Using rational numbers is not a limitation in that sense, but we must be careful to store rounded numbers where it matters. I think the approach implemented by Ledger is to keep as much of the original precision as possible.

Beancount chooses a decimal number representation to store the numbers parsed from the input with the same precision they are written as. This method suffers from the same problem as using rational numbers does in that the result of mathematical operations between the decimal numbers will currently be stored with their full precision (albeit in decimal). Admittedly, I have yet to apply explicit quantization where required, which would be the correct thing to do. A scheme has to be devised to infer suitable precisions for automatically quantizing the numbers after operations. The decimal representation provides natural opportunities for rounding after operations, and it is a suitable choice for this, implementations even typically provide a context for the precision to take place. Also note that it will never be required to store numbers to an infinite precision: the institutions never do it themselves.

-

HLedger, oddly enough, selects “double” fractional binary representation for its prices. This is an unfortunate choice, a worse one than using a precise representation: fractional decimal numbers input by the user are never represented precisely by their corresponding binary form. So all the numbers are incorrect but “close enough” that it works overall, and the only way to display a clean final result is by rounding to a suitable number of digits at the time of rendering a report. One could argue that the large number of digits provided by a 64-bit double representation is unlikely to cause significant errors given the quantity of operations we make… but binary rounding error could potentially accumulate, and the numbers are basically all incorrectly stored internally, rounded to their closest binary relative. Given that our task is accounting, why not just represent them correctly?

+

Hledger (since 2014) stores numbers internally as decimals allowing "unlimited" integral digits and up to 255 decimal digits.

Secondly, when checking that the postings of a transaction balance to zero, with all three systems it is necessary to allow for some tolerance on those amounts. This need is clear when you consider that inputting numbers in a text file implies a limited decimal representation. For example, if you’re going to multiply a number of units and a cost, say both written down with 2 fractional digits, you might end up with a number that has 4 fractional digits, and then you need to compare that result with a cash amount that would typically be entered with only 2 fractional digits. You need to allow for some looseness somehow.

The systems differ in how they choose that tolerance: