dev: rename/improve amountSetFullPrecisionUpTo, add mixedAmountSetFullPrecisionUpTo
This commit is contained in:
parent
ce0990d1e2
commit
3ec432bd53
@ -97,7 +97,7 @@ module Hledger.Data.Amount (
|
||||
amountSetPrecisionMax,
|
||||
withPrecision,
|
||||
amountSetFullPrecision,
|
||||
amountSetFullPrecisionOr,
|
||||
amountSetFullPrecisionUpTo,
|
||||
amountInternalPrecision,
|
||||
amountDisplayPrecision,
|
||||
defaultMaxPrecision,
|
||||
@ -159,6 +159,7 @@ module Hledger.Data.Amount (
|
||||
wbUnpack,
|
||||
mixedAmountSetPrecision,
|
||||
mixedAmountSetFullPrecision,
|
||||
mixedAmountSetFullPrecisionUpTo,
|
||||
mixedAmountSetPrecisionMin,
|
||||
mixedAmountSetPrecisionMax,
|
||||
|
||||
@ -453,24 +454,26 @@ amountSetFullPrecision a = amountSetPrecision p a
|
||||
|
||||
|
||||
-- | We often want to display "infinite decimal" amounts rounded to some readable
|
||||
-- number of digits, while still displaying amounts with a large "non infinite" number
|
||||
-- of decimal digits (eg, 100 or 200 digits) in full.
|
||||
-- number of digits, while still displaying amounts with a large but "non infinite"
|
||||
-- number of decimal digits (eg 10 or 100 or 200 digits) in full.
|
||||
-- This helper is like amountSetFullPrecision, but with some refinements:
|
||||
-- 1. If the internal precision is the maximum (255), indicating an infinite decimal,
|
||||
-- the display precision is set to a smaller hard-coded default (8).
|
||||
-- 2. A maximum display precision can be specified, setting a hard upper limit.
|
||||
--
|
||||
-- 1. A maximum display precision can be specified, setting a hard upper limit.
|
||||
--
|
||||
-- 2. If no limit is specified, and the internal precision is the maximum (255),
|
||||
-- indicating an infinite decimal, display precision is set to a smaller default (8).
|
||||
--
|
||||
-- This function always sets an explicit display precision (ie, Precision n).
|
||||
amountSetFullPrecisionOr :: Maybe Word8 -> Amount -> Amount
|
||||
amountSetFullPrecisionOr mmaxp a = amountSetPrecision (Precision p2) a
|
||||
--
|
||||
amountSetFullPrecisionUpTo :: Maybe Word8 -> Amount -> Amount
|
||||
amountSetFullPrecisionUpTo mmaxp a = amountSetPrecision (Precision p) a
|
||||
where
|
||||
p1 = if -- dbg0 "maxdigits" $
|
||||
amountHasMaxDigits a then defaultMaxPrecision else max disp intp
|
||||
-- & dbg0 "p1"
|
||||
p = case mmaxp of
|
||||
Just maxp -> min maxp $ max disp intp
|
||||
Nothing -> if amountHasMaxDigits a then defaultMaxPrecision else max disp intp
|
||||
where
|
||||
intp = amountInternalPrecision a
|
||||
disp = amountDisplayPrecision a
|
||||
p2 = maybe p1 (min p1) mmaxp
|
||||
-- & dbg0 "p2"
|
||||
intp = amountInternalPrecision a
|
||||
|
||||
-- | The fallback display precision used when showing amounts
|
||||
-- representing an infinite decimal.
|
||||
@ -1228,6 +1231,14 @@ mixedAmountSetPrecision p = mapMixedAmountUnsafe (amountSetPrecision p)
|
||||
mixedAmountSetFullPrecision :: MixedAmount -> MixedAmount
|
||||
mixedAmountSetFullPrecision = mapMixedAmountUnsafe amountSetFullPrecision
|
||||
|
||||
-- | In each component amount, increase the display precision sufficiently
|
||||
-- to render it exactly if possible, but not more than the given max precision,
|
||||
-- and if no max precision is given and the amount has infinite decimals,
|
||||
-- limit display precision to a hard-coded smaller number (8).
|
||||
-- See amountSetFullPrecisionUpTo.
|
||||
mixedAmountSetFullPrecisionUpTo :: Maybe Word8 -> MixedAmount -> MixedAmount
|
||||
mixedAmountSetFullPrecisionUpTo mmaxp = mapMixedAmountUnsafe (amountSetFullPrecisionUpTo mmaxp)
|
||||
|
||||
-- | In each component amount, ensure the display precision is at least the given value.
|
||||
-- Makes all amounts have an explicit Precision.
|
||||
mixedAmountSetPrecisionMin :: Word8 -> MixedAmount -> MixedAmount
|
||||
|
||||
@ -115,7 +115,7 @@ amountPriceDirectiveFromCost :: Day -> Amount -> Maybe PriceDirective
|
||||
amountPriceDirectiveFromCost d amt@Amount{acommodity=fromcomm, aquantity=n} = case acost amt of
|
||||
Just (UnitCost u) -> Just $ pd{pdamount=u}
|
||||
Just (TotalCost t) | n /= 0 -> Just $ pd{pdamount=u}
|
||||
where u = amountSetFullPrecisionOr Nothing $ divideAmount n t
|
||||
where u = amountSetFullPrecisionUpTo Nothing $ divideAmount n t
|
||||
_ -> Nothing
|
||||
where
|
||||
pd = PriceDirective{pddate = d, pdcommodity = fromcomm, pdamount = nullamt}
|
||||
@ -209,7 +209,7 @@ amountValueAtDate priceoracle styles mto d a =
|
||||
-- set the display precision to match the internal precision (showing all digits),
|
||||
-- unnormalised (don't strip trailing zeros);
|
||||
-- but if it looks like an infinite decimal, limit the precision to 8.
|
||||
& amountSetFullPrecisionOr Nothing
|
||||
& amountSetFullPrecisionUpTo Nothing
|
||||
& dbg9With (lbl "calculated value".showAmount)
|
||||
|
||||
-- | Calculate the gain of each component amount, that is the difference
|
||||
|
||||
@ -107,7 +107,7 @@ reversePriceDirective pd@PriceDirective{pdcommodity=c, pdamount=a}
|
||||
where
|
||||
lbl = lbl_ "reversePriceDirective"
|
||||
a' =
|
||||
amountSetFullPrecisionOr (Just defaultMaxPrecision) $
|
||||
amountSetFullPrecisionUpTo (Just defaultMaxPrecision) $
|
||||
invertAmount a{acommodity=c}
|
||||
& dbg9With (lbl "calculated reverse price".showAmount)
|
||||
-- & dbg9With (lbl "precision of reverse price".show.amountDisplayPrecision)
|
||||
|
||||
@ -147,7 +147,7 @@ roi CliOpts{rawopts_=rawopts, reportspec_=rspec@ReportSpec{_rsReportOpts=ReportO
|
||||
, T.pack $ showMixedAmount $ styleAmounts styles $ cashFlowAmt
|
||||
-- , T.pack $ showMixedAmount $
|
||||
-- -- dbg0With (lbl "cashflow after styling".showMixedAmountOneLine) $
|
||||
-- mapMixedAmount (amountSetFullPrecisionOr (Just defaultMaxPrecision)) $
|
||||
-- mapMixedAmount (amountSetFullPrecisionUpTo (Just defaultMaxPrecision)) $
|
||||
-- styleAmounts (styles
|
||||
-- -- & dbg0With (lbl "styles".show))
|
||||
-- cashFlowAmt
|
||||
|
||||
Loading…
Reference in New Issue
Block a user