lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 2b108ed7 18/27: Avoid unnecessary rounding


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 2b108ed7 18/27: Avoid unnecessary rounding
Date: Mon, 25 Apr 2022 12:56:16 -0400 (EDT)

branch: master
commit 2b108ed737d9f19640bb01e0a78ac916bc58742b
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Avoid unnecessary rounding
    
    Storing currency values as integer-valued doubles (cents) in the ledger
    object has made rounding unnecessary in many cases, some of which were
    dangerous. For example:
    
    -    return round_specamt().c(InvariantValues().SpecAmt[year] / 100.0);
    +    return from_cents(InvariantValues().SpecAmt[year]);
    
    Suppose specamt is rounded up to the next whole dollar, which is known
    to be the standard rule for at least one company. Then suppose the
    result of the division above is 1234567 plus epsilon. Then the intended
    value of 1234567 is incorrectly changed to 1234568. This commit removes
    that potential flaw.
---
 accountvalue.cpp |  3 +--
 ihs_acctval.cpp  |  6 ++----
 ihs_avsolve.cpp  | 19 +++++--------------
 solve.cpp        |  8 +++-----
 4 files changed, 11 insertions(+), 25 deletions(-)

diff --git a/accountvalue.cpp b/accountvalue.cpp
index 69f043de..11a04609 100644
--- a/accountvalue.cpp
+++ b/accountvalue.cpp
@@ -129,8 +129,7 @@ AccountValue::AccountValue(Input const& input)
 
 currency AccountValue::base_specamt(int year) const
 {
-    // CURRENCY !! Cents in ledger will make rounding unnecessary.
-    return round_specamt().c(InvariantValues().SpecAmt[year] / 100.0);
+    return from_cents(InvariantValues().SpecAmt[year]);
 }
 
 //============================================================================
diff --git a/ihs_acctval.cpp b/ihs_acctval.cpp
index e7c454ca..02b84a5b 100644
--- a/ihs_acctval.cpp
+++ b/ihs_acctval.cpp
@@ -148,16 +148,14 @@ AccountValue::AccountValue(Input const& input)
 
 currency AccountValue::base_specamt(int year) const
 {
-    // CURRENCY !! Cents in ledger will make rounding unnecessary.
-    return round_specamt().c(InvariantValues().SpecAmt[year] / 100.0);
+    return from_cents(InvariantValues().SpecAmt[year]);
 }
 
 /// Specified amount of term rider.
 
 currency AccountValue::term_specamt(int year) const
 {
-    // CURRENCY !! Cents in ledger will make rounding unnecessary.
-    return round_specamt().c(InvariantValues().TermSpecAmt[year] / 100.0);
+    return from_cents(InvariantValues().TermSpecAmt[year]);
 }
 
 /// Specified amount for 7702 (not 7702A).
diff --git a/ihs_avsolve.cpp b/ihs_avsolve.cpp
index f4dc859a..4ead6273 100644
--- a/ihs_avsolve.cpp
+++ b/ihs_avsolve.cpp
@@ -204,14 +204,11 @@ currency AccountValue::SolveTest
     currency most_negative_csv = C0;
     if(no_lapse_dur < SolveTargetDuration_)
         {
-        // CURRENCY !! Cents in ledger will make rounding unnecessary.
-        // But is that true? Ledger contains cents as double, not as currency.
-        most_negative_csv = round_minutiae().c
+        most_negative_csv = from_cents
             (*std::min_element
                 (VariantValues().CSVNet.begin() + no_lapse_dur
                 ,VariantValues().CSVNet.begin() + SolveTargetDuration_
                 )
-            / 100.0
             );
         }
 
@@ -237,19 +234,13 @@ currency AccountValue::SolveTest
     // SolveTargetDuration_ is in origin one. That's natural for loop
     // counters and iterators--it's one past the end--but indexing
     // must decrement it.
-    // CURRENCY !! Cents in ledger will make rounding unnecessary.
-    // But is that true? Ledger contains cents as double, not as currency.
-    currency value = 
round_minutiae().c(VariantValues().CSVNet[SolveTargetDuration_ - 1] / 100.0);
+    currency value = from_cents(VariantValues().CSVNet[SolveTargetDuration_ - 
1]);
     if(mce_solve_for_target_naar == SolveTarget_)
         {
-        // CURRENCY !! Cents in ledger will make rounding unnecessary.
-        value = round_minutiae().c
+        value = from_cents
             (
-                (
-                  VariantValues().EOYDeathBft[SolveTargetDuration_ - 1]
-                - VariantValues().AcctVal    [SolveTargetDuration_ - 1]
-                )
-            / 100.0
+              VariantValues().EOYDeathBft[SolveTargetDuration_ - 1]
+            - VariantValues().AcctVal    [SolveTargetDuration_ - 1]
             );
         }
     if(worst_negative < C0)
diff --git a/solve.cpp b/solve.cpp
index 7b08a246..9c5ab802 100644
--- a/solve.cpp
+++ b/solve.cpp
@@ -90,16 +90,14 @@ currency SolveTest()
         {
         Negative = std::min
             (Negative
-            // CURRENCY !! Cents in ledger will make rounding unnecessary.
-            ,round_to_cents.c(ConstThat->VariantValues().CSVNet[j] / 100.0)
+            ,from_cents(ConstThat->VariantValues().CSVNet[j])
 // Ideally, it'd be this:
-//          ,std::min(ConstThat->VariantValues().CSVNet[j] / 100.0, 
ConstThat->loan_ullage_[j])
+//          ,std::min(ConstThat->VariantValues().CSVNet[j], 
ConstThat->loan_ullage_[j])
 // but the antediluvian branch doesn't calculate ullage at all.
             );
         }
 
-    // CURRENCY !! Cents in ledger will make rounding unnecessary.
-    currency z = 
round_to_cents.c(ConstThat->VariantValues().CSVNet[ThatSolveTgtYear - 1] / 
100.0);
+    currency z = from_cents(ConstThat->VariantValues().CSVNet[ThatSolveTgtYear 
- 1]);
     if(Negative < C0)
         z = std::min(z, Negative);
     // IHS !! If SolveTgtYr within no-lapse period...see lmi.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]