From c7bcdfcdcf121942080d5bf177e83bb1fafee84c Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Mon, 16 Oct 2023 20:37:01 +0100 Subject: [PATCH] ;doc:internals: Precision and rounding --- hledger-lib/Hledger.hs | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/hledger-lib/Hledger.hs b/hledger-lib/Hledger.hs index 2b10f03d2..c5f3cd4db 100644 --- a/hledger-lib/Hledger.hs +++ b/hledger-lib/Hledger.hs @@ -19,6 +19,57 @@ or on Hackage (starting at [hledger-lib:Hledger](https://hackage.haskell.org/pac - [The README files](https://github.com/search?q=repo%3Asimonmichael%2Fhledger+path%3A**%2FREADME*&type=code&ref=advsearch) - [The high-level developer docs](https://hledger.org/dev.html) +== Miscellaneous notes + +=== Precision and rounding + +Numeric amounts in hledger are represented by "Decimal", +plus additional information like a "CommoditySymbol" +and an "AmountStyle" for display. +Together these form hledger's "Amount" type. + +In hledger docs, "precision" means the number of digits to the right of the decimal mark. +Amounts have several precisions we can talk about: + +- __Journal precision__ - the number of decimal digits recorded in the journal file / input data. + We accept up to 255 decimal digits there. + +- __Internal precision__ - the number of decimal digits stored internally in each Decimal value (after calling normalizeDecimal). + Decimal supports up to 255 decimal digits. + In amounts parsed from the journal, this will be the same as their journal precision. + In amounts generated from calculations, internal precision may increase, and will not decrease. + +- __Display precision__ - the number of decimal digits to be displayed in output ("AmountPrecision"); + this is part of the AmountStyle stored within each Amount. + Immediately after parsing, this is the same as the journal and internal precisions; + later it gets normalised, for consistent appearance. + When display precision is less than the internal precision, fewer, rounded decimal digits are displayed ("rounding"). + When display precision is greater than the internal precision, additional decimal zeros are displayed ("padding"). + +We use the term "display rounding" for applying a target display precision to an existing amount, +This can be done more or less forcefully, according to a "display rounding strategy", represented by the "Rounding" type. +This is stored within each AmountStyle for convenience, though semantically speaking it is not part of the amount. +The rounding strategies are: + +- none - leave the amount's display precision unchanged +- soft - add or remove trailing decimal zeros to approximate the target precision, but don't remove significant digits +- hard - use the exact target precision, possibly rounding and hiding significant digits +- all - do hard rounding of both the main amount and its cost amount (costs are normally not display-rounded). + +Here is when display rounding happens: + +1. After reading a journal, + all amounts have the standard commodity styles applied, but no display rounding is done. + (still needed ? seems so) + +2. After reading a journal, when checking each transaction for balancedness, + the transaction amounts are hard-rounded, temporarily, before calculating their sum. + (We'd like to update this to use local transaction precisions only.) + +3. Just before rendering report (since 1.31 or so). + Most reports do hard rounding; @print@ (and maybe other print-like commands ?) + can do any of the rounding strategies. + -} module Hledger (