lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master 6d719d2 10/15: Refactor an assertion


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 6d719d2 10/15: Refactor an assertion
Date: Mon, 25 Jan 2021 09:58:06 -0500 (EST)

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

    Refactor an assertion
    
    It may seem silly to assert this trivial invariant so frequently,
    but in practice it has failed uncomfortably often.
---
 account_value.hpp |  2 ++
 ihs_acctval.cpp   | 41 +++++++++++++++++++++++++++++++++++++----
 ihs_avmly.cpp     | 27 +++++++++------------------
 3 files changed, 48 insertions(+), 22 deletions(-)

diff --git a/account_value.hpp b/account_value.hpp
index 913d7bf..83ddf91 100644
--- a/account_value.hpp
+++ b/account_value.hpp
@@ -121,6 +121,8 @@ class LMI_SO AccountValue final
     currency specamt_for_7702(int year) const;
     currency specamt_for_7702A(int year) const;
 
+    void assert_pmts_add_up(char const* file, int line, int month);
+
     // We're not yet entirely sure how to handle ledger values. Right now,
     // we have pointers to a Ledger and also to its variant and invariant
     // parts. We put data into the parts, and then insert the parts into
diff --git a/ihs_acctval.cpp b/ihs_acctval.cpp
index 12e6e87..c69cfb8 100644
--- a/ihs_acctval.cpp
+++ b/ihs_acctval.cpp
@@ -47,7 +47,10 @@
 #include "stratified_algorithms.hpp"
 
 #include <algorithm>
+#include <cfloat>                       // DECIMAL_DIG
 #include <cmath>
+#include <iomanip>                      // setprecision()
+#include <ios>                          // ios_base::fixed()
 #include <iterator>                     // back_inserter()
 #include <limits>
 #include <numeric>
@@ -172,6 +175,36 @@ currency AccountValue::specamt_for_7702A(int year) const
         ;
 }
 
+void AccountValue::assert_pmts_add_up(char const* file, int line, int month)
+{
+    // If the currency unit is cents (as it ultimately will be), then
+    // all currency amounts should be an exact integral number of
+    // cents, and payments should add up exactly. For the nonce, the
+    // currency unit might not be cents, in which case payments should
+    // add up within a tiny tolerance.
+    bool const okay =
+#if defined CURRENCY_UNIT_IS_CENTS
+                         GrossPmts[month] ==   EeGrossPmts[month]     + 
ErGrossPmts[month]
+#else  // !defined CURRENCY_UNIT_IS_CENTS
+        materially_equal(dblize(GrossPmts[month]), dblize(EeGrossPmts[month]) 
+ dblize(ErGrossPmts[month]))
+#endif // !defined CURRENCY_UNIT_IS_CENTS
+        ;
+    if(okay)
+        return;
+
+    alarum()
+        << "Payments don't add up [file '" << file << "', line " << line << 
"]\n"
+        << month << " month\n"
+        << Year << " Year\n"
+        << std::fixed << std::setprecision(DECIMAL_DIG)
+        << EeGrossPmts[month] << " EeGrossPmts[month]\n"
+        << ErGrossPmts[month] << " ErGrossPmts[month]\n"
+        << GrossPmts[month] << " GrossPmts[month]\n"
+        << EeGrossPmts[month] + ErGrossPmts[month] << " EeGrossPmts[month] + 
ErGrossPmts[month]\n"
+        << LMI_FLUSH
+        ;
+}
+
 //============================================================================
 std::shared_ptr<Ledger const> AccountValue::ledger_from_av() const
 {
@@ -1307,10 +1340,10 @@ void AccountValue::FinalizeYear()
 
         for(int j = 0; j < 12; ++j)
             {
-            LMI_ASSERT(materially_equal(GrossPmts[j], EeGrossPmts[j] + 
ErGrossPmts[j]));
-            InvariantValues().GrossPmt  [Year]  += GrossPmts[j];
-            InvariantValues().EeGrossPmt[Year]  += EeGrossPmts[j];
-            InvariantValues().ErGrossPmt[Year]  += ErGrossPmts[j];
+            assert_pmts_add_up(__FILE__, __LINE__, j);
+            InvariantValues().GrossPmt  [Year]  += dblize(GrossPmts  [j]);
+            InvariantValues().EeGrossPmt[Year]  += dblize(EeGrossPmts[j]);
+            InvariantValues().ErGrossPmt[Year]  += dblize(ErGrossPmts[j]);
             }
         if(0 == Year)
             {
diff --git a/ihs_avmly.cpp b/ihs_avmly.cpp
index 479bab4..d73f660 100644
--- a/ihs_avmly.cpp
+++ b/ihs_avmly.cpp
@@ -613,12 +613,7 @@ void AccountValue::TxExch1035()
             );
         }
 
-    LMI_ASSERT
-        (materially_equal
-            (GrossPmts[Month]
-            ,EeGrossPmts[Month] + ErGrossPmts[Month]
-            )
-        );
+    assert_pmts_add_up(__FILE__, __LINE__, Month);
 }
 
 //============================================================================
@@ -1194,7 +1189,7 @@ void AccountValue::TxAscertainDesiredPayment()
         return;
         }
 
-    LMI_ASSERT(materially_equal(GrossPmts[Month], EeGrossPmts[Month] + 
ErGrossPmts[Month]));
+    assert_pmts_add_up(__FILE__, __LINE__, Month);
 
     double eepmt = 0.0;
     if(ee_pay_this_month)
@@ -1222,8 +1217,9 @@ void AccountValue::TxAscertainDesiredPayment()
         GrossPmts  [Month] += erpmt;
         }
 
-    LMI_ASSERT(materially_equal(GrossPmts[Month], EeGrossPmts[Month] + 
ErGrossPmts[Month]));
-    LMI_ASSERT(GrossPmts[Month] < 1.0e100);
+    assert_pmts_add_up(__FILE__, __LINE__, Month);
+    // bignum: the largest integer convertible to and from double.
+    LMI_ASSERT(GrossPmts[Month] < from_cents(1LL << 53));
 
     if(0 == Year && 0 == Month)
         {
@@ -1236,7 +1232,7 @@ void AccountValue::TxAscertainDesiredPayment()
         GrossPmts  [Month] += Dumpin;
         }
 
-    LMI_ASSERT(materially_equal(GrossPmts[Month], EeGrossPmts[Month] + 
ErGrossPmts[Month]));
+    assert_pmts_add_up(__FILE__, __LINE__, Month);
 }
 
 /// Limit payment (e.g., to the non-MEC maximum).
@@ -1256,7 +1252,7 @@ void AccountValue::TxLimitPayment(double a_maxpmt)
     // we shouldn't.
 // TODO ?? TAXATION !! Clean this up, and put GPT limit here, on prem net of 
WD.
 
-    LMI_ASSERT(materially_equal(GrossPmts[Month], EeGrossPmts[Month] + 
ErGrossPmts[Month]));
+    assert_pmts_add_up(__FILE__, __LINE__, Month);
 
     if(mce_reduce_prem == yare_input_.AvoidMecMethod && 
!Irc7702A_->IsMecAlready())
         {
@@ -1280,7 +1276,7 @@ void AccountValue::TxLimitPayment(double a_maxpmt)
         GrossPmts[Month] = EeGrossPmts[Month] + ErGrossPmts[Month];
         }
 
-    LMI_ASSERT(materially_equal(GrossPmts[Month], EeGrossPmts[Month] + 
ErGrossPmts[Month]));
+    assert_pmts_add_up(__FILE__, __LINE__, Month);
 
     if(Solving || mce_run_gen_curr_sep_full == RunBasis_)
         {
@@ -1294,12 +1290,7 @@ void AccountValue::TxLimitPayment(double a_maxpmt)
         GrossPmts[Month] = EeGrossPmts[Month] + ErGrossPmts[Month];
         }
 
-    LMI_ASSERT
-        (materially_equal
-            (GrossPmts[Month]
-            ,EeGrossPmts[Month] + ErGrossPmts[Month]
-            )
-        );
+    assert_pmts_add_up(__FILE__, __LINE__, Month);
 }
 
 //============================================================================



reply via email to

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