[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] valyuta/005 dfdbf3c 16/17: Use currency type for cla
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] valyuta/005 dfdbf3c 16/17: Use currency type for class members as appropriate |
Date: |
Sat, 16 Jan 2021 21:06:19 -0500 (EST) |
branch: valyuta/005
commit dfdbf3c5a73781f7f4ece09b60ad25c0e1aab54e
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Use currency type for class members as appropriate
Changed 'double' to 'currency', in every class, for every appropriate
data member and function signature (all of which now match the latest
"valyuta" branch). Did not change function implementations or types of
local variables--they can later be changed piecemeal.
As expected, with
using currency = double;
the effect on speed is negligible.
---
Speed_gcc_i686-w64-mingw32 | 12 +-
Speed_gcc_x86_64-pc-linux-gnu | 12 +-
Speed_gcc_x86_64-w64-mingw32 | 12 +-
account_value.hpp | 515 +++++++++++++++++++++---------------------
accountvalue.cpp | 10 +-
basic_values.hpp | 134 +++++------
basicvalues.cpp | 16 +-
death_benefits.cpp | 4 +-
death_benefits.hpp | 17 +-
gpt_specamt.cpp | 21 +-
gpt_specamt.hpp | 13 +-
ihs_acctval.cpp | 31 +--
ihs_avmly.cpp | 57 ++---
ihs_avsolve.cpp | 26 ++-
ihs_avstrtgy.cpp | 12 +-
ihs_basicval.cpp | 94 ++++----
loads.hpp | 45 ++--
loads_impl.hpp | 81 ++++---
outlay.cpp | 14 +-
outlay.hpp | 57 ++---
solve.cpp | 34 +--
21 files changed, 629 insertions(+), 588 deletions(-)
diff --git a/Speed_gcc_i686-w64-mingw32 b/Speed_gcc_i686-w64-mingw32
index 6b0f9cb..cfb749f 100644
--- a/Speed_gcc_i686-w64-mingw32
+++ b/Speed_gcc_i686-w64-mingw32
@@ -1,7 +1,7 @@
Test speed:
- naic, no solve : 5.456e-02 s mean; 51931 us least of 19 runs
- naic, specamt solve : 9.267e-02 s mean; 92286 us least of 11 runs
- naic, ee prem solve : 8.516e-02 s mean; 84830 us least of 12 runs
- finra, no solve : 2.183e-02 s mean; 21703 us least of 46 runs
- finra, specamt solve: 5.913e-02 s mean; 58925 us least of 17 runs
- finra, ee prem solve: 5.501e-02 s mean; 54808 us least of 19 runs
+ naic, no solve : 5.244e-02 s mean; 52015 us least of 20 runs
+ naic, specamt solve : 9.343e-02 s mean; 92665 us least of 11 runs
+ naic, ee prem solve : 8.574e-02 s mean; 85253 us least of 12 runs
+ finra, no solve : 2.275e-02 s mean; 21555 us least of 44 runs
+ finra, specamt solve: 5.958e-02 s mean; 58773 us least of 17 runs
+ finra, ee prem solve: 5.560e-02 s mean; 54771 us least of 18 runs
diff --git a/Speed_gcc_x86_64-pc-linux-gnu b/Speed_gcc_x86_64-pc-linux-gnu
index dad77b7..aedbb5f 100644
--- a/Speed_gcc_x86_64-pc-linux-gnu
+++ b/Speed_gcc_x86_64-pc-linux-gnu
@@ -1,7 +1,7 @@
Test speed:
- naic, no solve : 1.918e-02 s mean; 18753 us least of 53 runs
- naic, specamt solve : 3.312e-02 s mean; 32434 us least of 31 runs
- naic, ee prem solve : 3.046e-02 s mean; 30031 us least of 33 runs
- finra, no solve : 7.629e-03 s mean; 7377 us least of 100 runs
- finra, specamt solve: 2.056e-02 s mean; 20093 us least of 49 runs
- finra, ee prem solve: 1.913e-02 s mean; 18751 us least of 53 runs
+ naic, no solve : 1.981e-02 s mean; 18713 us least of 51 runs
+ naic, specamt solve : 3.313e-02 s mean; 32640 us least of 31 runs
+ naic, ee prem solve : 3.044e-02 s mean; 29950 us least of 33 runs
+ finra, no solve : 7.627e-03 s mean; 7194 us least of 100 runs
+ finra, specamt solve: 2.051e-02 s mean; 20047 us least of 49 runs
+ finra, ee prem solve: 1.918e-02 s mean; 18550 us least of 53 runs
diff --git a/Speed_gcc_x86_64-w64-mingw32 b/Speed_gcc_x86_64-w64-mingw32
index 139c622..16222b3 100644
--- a/Speed_gcc_x86_64-w64-mingw32
+++ b/Speed_gcc_x86_64-w64-mingw32
@@ -1,7 +1,7 @@
Test speed:
- naic, no solve : 2.674e-02 s mean; 26388 us least of 38 runs
- naic, specamt solve : 4.206e-02 s mean; 41541 us least of 24 runs
- naic, ee prem solve : 3.916e-02 s mean; 38679 us least of 26 runs
- finra, no solve : 1.476e-02 s mean; 14484 us least of 68 runs
- finra, specamt solve: 2.882e-02 s mean; 28440 us least of 35 runs
- finra, ee prem solve: 2.728e-02 s mean; 26912 us least of 37 runs
+ naic, no solve : 2.679e-02 s mean; 26410 us least of 38 runs
+ naic, specamt solve : 4.213e-02 s mean; 41548 us least of 24 runs
+ naic, ee prem solve : 3.923e-02 s mean; 38721 us least of 26 runs
+ finra, no solve : 1.468e-02 s mean; 14383 us least of 69 runs
+ finra, specamt solve: 2.881e-02 s mean; 28406 us least of 35 runs
+ finra, ee prem solve: 2.739e-02 s mean; 26940 us least of 37 runs
diff --git a/account_value.hpp b/account_value.hpp
index cf01e82..913d7bf 100644
--- a/account_value.hpp
+++ b/account_value.hpp
@@ -25,6 +25,7 @@
#include "config.hpp"
#include "basic_values.hpp"
+#include "currency.hpp"
#include "oecumenic_enumerations.hpp"
#include "so_attributes.hpp"
@@ -50,7 +51,7 @@ class LMI_SO AccountValue final
{
friend class SolveHelper;
friend class run_census_in_parallel;
- friend double SolveTest();
+ friend currency SolveTest(); // Antediluvian.
public:
enum {months_per_year = 12};
@@ -64,29 +65,29 @@ class LMI_SO AccountValue final
void SetDebugFilename (std::string const&);
void SolveSetPmts // Antediluvian.
- (double a_Pmt
- ,int ThatSolveBegYear
- ,int ThatSolveEndYear
+ (currency a_Pmt
+ ,int ThatSolveBegYear
+ ,int ThatSolveEndYear
);
void SolveSetSpecAmt // Antediluvian.
- (double a_Bft
- ,int ThatSolveBegYear
- ,int ThatSolveEndYear
+ (currency a_Bft
+ ,int ThatSolveBegYear
+ ,int ThatSolveEndYear
);
void SolveSetLoans // Antediluvian.
- (double a_Loan
- ,int ThatSolveBegYear
- ,int ThatSolveEndYear
+ (currency a_Loan
+ ,int ThatSolveBegYear
+ ,int ThatSolveEndYear
);
void SolveSetWDs // Antediluvian.
- (double a_WD
- ,int ThatSolveBegYear
- ,int ThatSolveEndYear
+ (currency a_WD
+ ,int ThatSolveBegYear
+ ,int ThatSolveEndYear
);
void SolveSetLoanThenWD // Antediluvian.
- (double a_Amt
- ,int ThatSolveBegYear
- ,int ThatSolveEndYear
+ (currency a_Amt
+ ,int ThatSolveBegYear
+ ,int ThatSolveEndYear
);
std::shared_ptr<Ledger const> ledger_from_av() const;
@@ -100,25 +101,25 @@ class LMI_SO AccountValue final
int GetLength () const;
- double InforceLivesBoy () const;
- double InforceLivesEoy () const;
- double GetSepAcctAssetsInforce () const;
+ double InforceLivesBoy () const;
+ double InforceLivesEoy () const;
+ currency GetSepAcctAssetsInforce() const;
- void process_payment (double);
- void IncrementAVProportionally(double);
- void IncrementAVPreferentially(double, oenum_increment_account_preference);
- void process_deduction (double);
- void process_distribution (double);
- void DecrementAVProportionally(double);
- void DecrementAVProgressively (double, oenum_increment_account_preference);
+ void process_payment (currency);
+ void IncrementAVProportionally(currency);
+ void IncrementAVPreferentially(currency,
oenum_increment_account_preference);
+ void process_deduction (currency);
+ void process_distribution (currency);
+ void DecrementAVProportionally(currency);
+ void DecrementAVProgressively (currency,
oenum_increment_account_preference);
- double TotalAccountValue() const;
- double CashValueFor7702() const;
+ currency TotalAccountValue() const;
+ currency CashValueFor7702() const;
- double base_specamt(int year) const;
- double term_specamt(int year) const;
- double specamt_for_7702(int year) const;
- double specamt_for_7702A(int year) const;
+ currency base_specamt(int year) const;
+ currency term_specamt(int year) const;
+ currency specamt_for_7702(int year) const;
+ currency specamt_for_7702A(int year) const;
// 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
@@ -152,11 +153,11 @@ class LMI_SO AccountValue final
,int a_InforceMonth = 0
);
- void SolveSetSpecAmt (double a_CandidateValue);
- void SolveSetEePrem (double a_CandidateValue);
- void SolveSetErPrem (double a_CandidateValue);
- void SolveSetLoan (double a_CandidateValue);
- void SolveSetWD (double a_CandidateValue);
+ void SolveSetSpecAmt (currency a_CandidateValue);
+ void SolveSetEePrem (currency a_CandidateValue);
+ void SolveSetErPrem (currency a_CandidateValue);
+ void SolveSetLoan (currency a_CandidateValue);
+ void SolveSetWD (currency a_CandidateValue);
void DebugPrint ();
@@ -177,57 +178,57 @@ class LMI_SO AccountValue final
// to the point where interest is credited.
// Process monthly transactions up to but excluding interest credit
- double IncrementBOM
- (int year
- ,int month
+ currency IncrementBOM
+ (int year
+ ,int month
,double a_case_k_factor
);
// Credit interest and process all subsequent monthly transactions
void IncrementEOM
- (int year
- ,int month
- ,double assets_post_bom
- ,double cum_pmts_post_bom
+ (int year
+ ,int month
+ ,currency assets_post_bom
+ ,currency cum_pmts_post_bom
);
void IncrementEOY(int year);
bool PrecedesInforceDuration(int year, int month);
- double Solve(); // Antediluvian.
- double Solve
+ currency Solve(); // Antediluvian.
+ currency Solve
(mcenum_solve_type a_SolveType
,int a_SolveBeginYear
,int a_SolveEndYear
,mcenum_solve_target a_SolveTarget
- ,double a_SolveTargetCsv
+ ,currency a_SolveTargetCsv
,int a_SolveTargetYear
,mcenum_gen_basis a_SolveGenBasis
,mcenum_sep_basis a_SolveSepBasis
);
- double SolveTest (double a_CandidateValue);
+ currency SolveTest (currency a_CandidateValue);
- double SolveGuarPremium ();
+ currency SolveGuarPremium ();
void PerformSpecAmtStrategy();
void PerformSupplAmtStrategy();
- double CalculateSpecAmtFromStrategy
+ currency CalculateSpecAmtFromStrategy
(int actual_year
,int reference_year
- ,double explicit_value
+ ,currency explicit_value
,mcenum_sa_strategy strategy
) const;
- void PerformPmtStrategy(double* a_Pmt); // Antediluvian.
- double PerformEePmtStrategy () const;
- double PerformErPmtStrategy () const;
- double DoPerformPmtStrategy
+ void PerformPmtStrategy(currency* a_Pmt); // Antediluvian.
+ currency PerformEePmtStrategy () const;
+ currency PerformErPmtStrategy () const;
+ currency DoPerformPmtStrategy
(mcenum_solve_type a_SolveForWhichPrem
,mcenum_mode a_CurrentMode
,mcenum_mode a_InitialMode
,double a_TblMult
- ,std::vector<double> const& a_PmtVector
+ ,std::vector<currency> const& a_PmtVector
,std::vector<mcenum_pmt_strategy> const& a_StrategyVector
) const;
@@ -238,15 +239,15 @@ class LMI_SO AccountValue final
void TxTestGPT ();
void TxPmt(); // Antediluvian.
void TxAscertainDesiredPayment ();
- void TxLimitPayment (double a_maxpmt);
+ void TxLimitPayment (double a_maxpmt); // CURRENCY !! not
currency?
void TxRecognizePaymentFor7702A
- (double a_pmt
- ,bool a_this_payment_is_unnecessary
+ (currency a_pmt
+ ,bool a_this_payment_is_unnecessary
);
- void TxAcceptPayment (double payment);
- double GetPremLoad
- (double a_pmt
- ,double a_portion_exempt_from_premium_tax
+ void TxAcceptPayment (currency payment);
+ currency GetPremLoad
+ (currency a_pmt
+ ,currency a_portion_exempt_from_premium_tax
);
void TxLoanRepay ();
@@ -272,35 +273,36 @@ class LMI_SO AccountValue final
// Reflects optional daily interest accounting.
double ActualMonthlyRate (double monthly_rate) const;
- double InterestCredited
- (double principal
- ,double monthly_rate
+ currency InterestCredited
+ (currency principal
+ ,double monthly_rate
) const;
- bool IsModalPmtDate (mcenum_mode) const;
- bool IsModalPmtDate (); // Antediluvian.
- int MonthsToNextModalPmtDate() const;
- double anticipated_deduction (mcenum_anticipated_deduction);
+ bool IsModalPmtDate (mcenum_mode) const;
+ bool IsModalPmtDate (); // Antediluvian.
+ int MonthsToNextModalPmtDate() const;
+ currency anticipated_deduction (mcenum_anticipated_deduction);
- double minimum_specified_amount(bool issuing_now, bool term_rider) const;
- void ChangeSpecAmtBy (double delta);
- void ChangeSupplAmtBy (double delta);
+ currency minimum_specified_amount(bool issuing_now, bool term_rider) const;
+ void ChangeSpecAmtBy (currency delta);
+ void ChangeSupplAmtBy (currency delta);
- double SurrChg () const;
- double CSVBoost () const;
+ currency SurrChg () const;
+ currency CSVBoost () const;
- void set_list_bill_year_and_month();
- void set_list_bill_premium();
- void set_modal_min_premium();
+ void set_list_bill_year_and_month();
+ void set_list_bill_premium();
+ void set_modal_min_premium();
- void SetMaxLoan ();
- void SetMaxWD ();
- double GetRefundableSalesLoad () const;
+ void SetMaxLoan ();
+ void SetMaxWD ();
+ currency GetRefundableSalesLoad() const;
- void ApplyDynamicMandE (double assets);
+ void ApplyDynamicMandE (currency assets);
- void SetMonthlyDetail(int enumerator, std::string const& s);
- void SetMonthlyDetail(int enumerator, double d);
+ void SetMonthlyDetail(int enumerator, std::string const&);
+ void SetMonthlyDetail(int enumerator, double);
+// void SetMonthlyDetail(int enumerator, currency); // CURRENCY !! later...
void DebugPrintInit();
void DebugEndBasis();
@@ -313,12 +315,12 @@ class LMI_SO AccountValue final
std::ofstream DebugStream;
std::vector<std::string> DebugRecord;
- double PriorAVGenAcct;
- double PriorAVSepAcct;
- double PriorAVRegLn;
- double PriorAVPrfLn;
- double PriorRegLnBal;
- double PriorPrfLnBal;
+ currency PriorAVGenAcct;
+ currency PriorAVSepAcct;
+ currency PriorAVRegLn;
+ currency PriorAVPrfLn;
+ currency PriorRegLnBal;
+ currency PriorPrfLnBal;
// Mode flags.
bool Debugging;
@@ -339,13 +341,13 @@ class LMI_SO AccountValue final
oenum_allocation_method er_premium_allocation_method;
oenum_increment_account_preference er_premium_preferred_account;
- double GuarPremium;
+ currency GuarPremium;
// These data members make Solve() arguments available to SolveTest().
int SolveBeginYear_;
int SolveEndYear_;
mcenum_solve_target SolveTarget_;
- double SolveTargetCsv_;
+ currency SolveTargetCsv_;
int SolveTargetDuration_;
mcenum_gen_basis SolveGenBasis_;
mcenum_sep_basis SolveSepBasis_;
@@ -354,132 +356,132 @@ class LMI_SO AccountValue final
mcenum_gen_basis GenBasis_;
mcenum_sep_basis SepBasis_;
- int LapseMonth; // Antediluvian.
- int LapseYear; // Antediluvian.
+ int LapseMonth; // Antediluvian.
+ int LapseYear; // Antediluvian.
- double External1035Amount;
- double Internal1035Amount;
- double Dumpin;
+ currency External1035Amount;
+ currency Internal1035Amount;
+ currency Dumpin;
- double MlyNoLapsePrem;
- double CumNoLapsePrem;
- bool NoLapseActive;
+ currency MlyNoLapsePrem;
+ currency CumNoLapsePrem;
+ bool NoLapseActive;
// Solves need to know when a no-lapse guarantee is active.
// Prefer int here because vector<bool> is not a container.
std::vector<int> YearlyNoLapseActive;
// Ullage is any positive excess of amount requested over amount available.
- std::vector<double> loan_ullage_;
- std::vector<double> withdrawal_ullage_;
+ std::vector<currency> loan_ullage_;
+ std::vector<currency> withdrawal_ullage_;
- double CumPmts;
- double TaxBasis;
+ currency CumPmts;
+ currency TaxBasis;
// This supports solves for tax basis. Eventually it should be
// moved into the invariant-ledger class.
- std::vector<double> YearlyTaxBasis;
+ std::vector<currency> YearlyTaxBasis;
// Ee- and Er-GrossPmts aren't used directly in the AV calculations.
// They must be kept separate for ledger output, and also for
// tax basis calculations (when we fix that).
- std::vector<double> GrossPmts;
- std::vector<double> EeGrossPmts;
- std::vector<double> ErGrossPmts;
- std::vector<double> NetPmts;
+ std::vector<currency> GrossPmts;
+ std::vector<currency> EeGrossPmts;
+ std::vector<currency> ErGrossPmts;
+ std::vector<currency> NetPmts;
// Reproposal input.
- int InforceYear;
- int InforceMonth;
- double InforceAVGenAcct;
- double InforceAVSepAcct;
- double InforceAVRegLn;
- double InforceAVPrfLn;
- double InforceRegLnBal;
- double InforcePrfLnBal;
- double InforceCumNoLapsePrem;
- double InforceBasis;
- double InforceCumPmts;
- double InforceTaxBasis;
- double InforceLoanBalance;
+ int InforceYear;
+ int InforceMonth;
+ currency InforceAVGenAcct;
+ currency InforceAVSepAcct;
+ currency InforceAVRegLn;
+ currency InforceAVPrfLn;
+ currency InforceRegLnBal;
+ currency InforcePrfLnBal;
+ currency InforceCumNoLapsePrem;
+ currency InforceBasis;
+ currency InforceCumPmts;
+ currency InforceTaxBasis;
+ currency InforceLoanBalance;
// Intermediate values.
- int Year;
- int Month;
- int MonthsSinceIssue;
- bool daily_interest_accounting;
- int days_in_policy_month;
- int days_in_policy_year;
- double AVGenAcct;
- double AVSepAcct;
- double SepAcctValueAfterDeduction;
- double GenAcctPaymentAllocation;
- double SepAcctPaymentAllocation;
- double NAAR;
- double CoiCharge;
- double RiderCharges;
- double NetCoiCharge;
- double SpecAmtLoadBase;
- double DacTaxRsv;
-
- double AVUnloaned; // Antediluvian.
-
- double NetMaxNecessaryPremium;
- double GrossMaxNecessaryPremium;
- double NecessaryPremium;
- double UnnecessaryPremium;
-
- // 7702A CVAT deemed cash value.
- double Dcv;
- double DcvDeathBft;
- double DcvNaar;
- double DcvCoiCharge;
- double DcvTermCharge;
- double DcvWpCharge;
+ int Year;
+ int Month;
+ int MonthsSinceIssue;
+ bool daily_interest_accounting;
+ int days_in_policy_month;
+ int days_in_policy_year;
+ currency AVGenAcct;
+ currency AVSepAcct;
+ currency SepAcctValueAfterDeduction;
+ double GenAcctPaymentAllocation;
+ double SepAcctPaymentAllocation;
+ double NAAR; // CURRENCY !! not currency?
+ currency CoiCharge;
+ currency RiderCharges;
+ currency NetCoiCharge;
+ currency SpecAmtLoadBase;
+ double DacTaxRsv; // CURRENCY !! obsolete--always zero
+
+ currency AVUnloaned; // Antediluvian.
+
+ currency NetMaxNecessaryPremium;
+ currency GrossMaxNecessaryPremium;
+ currency NecessaryPremium;
+ currency UnnecessaryPremium;
+
+ // 7702A CVAT deemed cash value. CURRENCY !! not currency?
+ double Dcv;
+ double DcvDeathBft;
+ double DcvNaar;
+ double DcvCoiCharge;
+ double DcvTermCharge;
+ double DcvWpCharge;
// For other riders like AD&D, charge for DCV = charge otherwise.
// Honeymoon provision.
- bool HoneymoonActive;
- double HoneymoonValue;
+ bool HoneymoonActive;
+ currency HoneymoonValue;
// 7702 GPT
- double GptForceout;
- double YearsTotalGptForceout;
+ currency GptForceout;
+ currency YearsTotalGptForceout;
// Intermediate values within annual or monthly loop only.
- double pmt; // Antediluvian.
+ currency pmt; // Antediluvian.
mcenum_mode pmt_mode; // Antediluvian.
int ModeIndex; // Antediluvian.
- double GenAcctIntCred;
- double SepAcctIntCred;
- double RegLnIntCred;
- double PrfLnIntCred;
- double AVRegLn;
- double AVPrfLn;
- double RegLnBal;
- double PrfLnBal;
- double MaxLoan;
- double UnusedTargetPrem;
- double AnnualTargetPrem;
- double MaxWD;
- double GrossWD;
- double NetWD;
- double CumWD;
-
- double wd; // Antediluvian.
- double mlyguarv; // Antediluvian.
+ currency GenAcctIntCred;
+ currency SepAcctIntCred;
+ currency RegLnIntCred;
+ currency PrfLnIntCred;
+ currency AVRegLn;
+ currency AVPrfLn;
+ currency RegLnBal;
+ currency PrfLnBal;
+ currency MaxLoan;
+ currency UnusedTargetPrem;
+ currency AnnualTargetPrem;
+ currency MaxWD;
+ currency GrossWD;
+ currency NetWD;
+ currency CumWD;
+
+ currency wd; // Antediluvian.
+ double mlyguarv; // Antediluvian.
// For GPT: SA, DB, and DBOpt before the day's transactions are applied.
- double OldSA;
- double OldDB;
+ currency OldSA;
+ currency OldDB;
mcenum_dbopt OldDBOpt;
// Permanent invariants are in class BasicValues; these are
// annual invariants.
double YearsCorridorFactor;
mcenum_dbopt YearsDBOpt;
- double YearsAnnualPolicyFee;
- double YearsMonthlyPolicyFee;
+ currency YearsAnnualPolicyFee;
+ currency YearsMonthlyPolicyFee;
double YearsGenAcctIntRate;
double YearsSepAcctIntRate;
@@ -515,105 +517,106 @@ class LMI_SO AccountValue final
double YearsSalesLoadRefundRate;
double YearsDacTaxLoadRate;
- double MonthsPolicyFees;
- double SpecAmtLoad;
- double premium_load_;
- double sales_load_;
- double premium_tax_load_;
- double dac_tax_load_;
+ currency MonthsPolicyFees;
+ currency SpecAmtLoad;
+ // Premium load is (rounded) currency; its components are not.
+ double premium_load_;
+ double sales_load_;
+ double premium_tax_load_;
+ double dac_tax_load_;
// Stratified loads are determined by assets and cumulative
// payments immediately after the monthly deduction. Both are
// stored at the proper moment, where they're constrained to be
// nonnegative. Stratified loads happen to be used only for the
// separate account.
- double AssetsPostBom;
- double CumPmtsPostBom;
- double SepAcctLoad;
-
- double case_k_factor;
- double ActualCoiRate;
-
- bool SplitMinPrem;
- bool UnsplitSplitMinPrem;
-
- int list_bill_year_ {methuselah};
- int list_bill_month_ {13};
-
- bool TermCanLapse;
- bool TermRiderActive;
- double ActualSpecAmt;
- double TermSpecAmt;
- double TermDB;
- double DB7702A;
- double DBIgnoringCorr;
- double DBReflectingCorr;
-
- double deathbft; // Antediluvian.
- bool haswp; // Antediluvian.
- bool hasadb; // Antediluvian.
-
- double ActualLoan;
- double RequestedLoan;
- double RequestedWD;
-
- double AdbCharge;
- double SpouseRiderCharge;
- double ChildRiderCharge;
- double WpCharge;
- double TermCharge;
-
- double MlyDed;
- double mlydedtonextmodalpmtdate; // Antediluvian.
-
- double YearsTotalCoiCharge;
- double YearsTotalRiderCharges;
- double YearsAVRelOnDeath;
- double YearsLoanRepaidOnDeath;
- double YearsGrossClaims;
- double YearsDeathProceeds;
- double YearsNetClaims;
- double YearsTotalNetIntCredited;
- double YearsTotalGrossIntCredited;
- double YearsTotalLoanIntAccrued;
- double YearsTotalPolicyFee;
- double YearsTotalDacTaxLoad;
- double YearsTotalSpecAmtLoad;
- double YearsTotalSepAcctLoad;
+ currency AssetsPostBom;
+ currency CumPmtsPostBom;
+ currency SepAcctLoad;
+
+ double case_k_factor;
+ double ActualCoiRate;
+
+ bool SplitMinPrem;
+ bool UnsplitSplitMinPrem;
+
+ int list_bill_year_ {methuselah};
+ int list_bill_month_ {13};
+
+ bool TermCanLapse;
+ bool TermRiderActive;
+ currency ActualSpecAmt;
+ currency TermSpecAmt;
+ currency TermDB;
+ currency DB7702A;
+ currency DBIgnoringCorr;
+ currency DBReflectingCorr;
+
+ currency deathbft; // Antediluvian.
+ bool haswp; // Antediluvian.
+ bool hasadb; // Antediluvian.
+
+ currency ActualLoan;
+ currency RequestedLoan;
+ currency RequestedWD;
+
+ currency AdbCharge;
+ currency SpouseRiderCharge;
+ currency ChildRiderCharge;
+ currency WpCharge;
+ currency TermCharge;
+
+ currency MlyDed;
+ currency mlydedtonextmodalpmtdate; // Antediluvian.
+
+ currency YearsTotalCoiCharge;
+ currency YearsTotalRiderCharges;
+ double YearsAVRelOnDeath;
+ double YearsLoanRepaidOnDeath;
+ double YearsGrossClaims;
+ double YearsDeathProceeds;
+ double YearsNetClaims;
+ currency YearsTotalNetIntCredited;
+ currency YearsTotalGrossIntCredited;
+ currency YearsTotalLoanIntAccrued;
+ currency YearsTotalPolicyFee;
+ double YearsTotalDacTaxLoad; // cumulative (unrounded) 'dac_tax_load_'
+ currency YearsTotalSpecAmtLoad;
+ currency YearsTotalSepAcctLoad;
// For experience rating.
- double CoiRetentionRate;
- double ExperienceRatingAmortizationYears;
- double IbnrAsMonthsOfMortalityCharges;
- double NextYearsProjectedCoiCharge;
- double YearsTotalNetCoiCharge;
+ double CoiRetentionRate;
+ double ExperienceRatingAmortizationYears;
+ double IbnrAsMonthsOfMortalityCharges;
+ double NextYearsProjectedCoiCharge;
+ double YearsTotalNetCoiCharge;
- double CumulativeSalesLoad;
+ currency CumulativeSalesLoad;
// Illustrated outlay must be the same for current, guaranteed,
// and all other bases. Outlay components are set on whichever
// basis governs, usually current, then stored for use with all
// other bases.
- std::vector<double> OverridingPmts; // Antediluvian.
- std::vector<double> stored_pmts; // Antediluvian.
+ std::vector<currency> OverridingPmts; // Antediluvian.
+ std::vector<currency> stored_pmts; // Antediluvian.
- std::vector<double> OverridingEePmts;
- std::vector<double> OverridingErPmts;
+ std::vector<currency> OverridingEePmts;
+ std::vector<currency> OverridingErPmts;
// We need no 'OverridingDumpin' because we simply treat dumpin as
// employee premium.
- double OverridingExternal1035Amount;
- double OverridingInternal1035Amount;
+ currency OverridingExternal1035Amount;
+ currency OverridingInternal1035Amount;
- std::vector<double> OverridingLoan;
- std::vector<double> OverridingWD;
+ std::vector<currency> OverridingLoan;
+ std::vector<currency> OverridingWD;
- std::vector<double> SurrChg_; // Of uncertain utility.
+ std::vector<currency> SurrChg_; // Of uncertain utility.
};
//============================================================================
-inline double AccountValue::TotalAccountValue() const
+inline currency AccountValue::TotalAccountValue() const
{
return AVGenAcct + AVSepAcct + AVRegLn + AVPrfLn;
}
diff --git a/accountvalue.cpp b/accountvalue.cpp
index f2c72c5..1aa44e7 100644
--- a/accountvalue.cpp
+++ b/accountvalue.cpp
@@ -126,7 +126,7 @@ AccountValue::AccountValue(Input const& input)
/// Specified amount.
-double AccountValue::base_specamt(int year) const
+currency AccountValue::base_specamt(int year) const
{
return InvariantValues().SpecAmt[year];
}
@@ -587,7 +587,7 @@ void AccountValue::TxSpecAmtChange()
//============================================================================
// Set payment according to selected strategy, in each non-solve year.
-void AccountValue::PerformPmtStrategy(double* a_Pmt)
+void AccountValue::PerformPmtStrategy(currency* a_Pmt)
{
// Don't override premium during solve period.
if
@@ -1054,11 +1054,11 @@ double AccountValue::GetCurtateNetCoiChargeInforce()
const
{return 0.0;}
double AccountValue::GetProjectedCoiChargeInforce() const
{return 0.0;}
-double AccountValue::GetSepAcctAssetsInforce() const
+currency AccountValue::GetSepAcctAssetsInforce() const
{return 0.0;}
-double AccountValue::IncrementBOM(int, int, double)
+currency AccountValue::IncrementBOM(int, int, double)
{return 0.0;}
-void AccountValue::IncrementEOM(int, int, double, double)
+void AccountValue::IncrementEOM(int, int, currency, currency)
{return;}
void AccountValue::IncrementEOY(int)
{return;}
diff --git a/basic_values.hpp b/basic_values.hpp
index a80da77..6fae516 100644
--- a/basic_values.hpp
+++ b/basic_values.hpp
@@ -25,6 +25,7 @@
#include "config.hpp"
#include "actuarial_table.hpp" // e_actuarial_table_method
+#include "currency.hpp"
#include "database.hpp"
#include "dbnames.hpp" // e_database_key
#include "mc_enum_type_enums.hpp"
@@ -135,7 +136,7 @@ class LMI_SO BasicValues
product_data const& product () const {return product_;}
product_database const& database() const {return database_;}
- double GetAnnualTgtPrem(int a_year, double a_specamt) const;
+ currency GetAnnualTgtPrem(int a_year, currency a_specamt) const;
std::vector<double> const& GetCorridorFactor() const;
std::vector<double> const& SpreadFor7702() const;
@@ -200,89 +201,89 @@ class LMI_SO BasicValues
round_to<double> const& round_minutiae () const {return
round_minutiae_ ;}
protected:
- double GetModalMinPrem
+ currency GetModalMinPrem
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const;
- double GetModalTgtPrem
+ currency GetModalTgtPrem
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const;
- double GetModalPremMaxNonMec
+ currency GetModalPremMaxNonMec
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const;
- double GetModalPremMinFromTable
+ currency GetModalPremMinFromTable
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const;
- double GetModalPremTgtFromTable
+ currency GetModalPremTgtFromTable
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const;
- double GetModalPremProxyTable
+ currency GetModalPremProxyTable
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
,double a_table_multiplier
) const;
- double GetModalPremCorridor
+ currency GetModalPremCorridor
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const;
- double GetModalPremGLP
+ currency GetModalPremGLP
(int a_duration
,mcenum_mode a_mode
- ,double a_bft_amt
- ,double a_specamt
+ ,currency a_bft_amt
+ ,currency a_specamt
) const;
- double GetModalPremGSP
+ currency GetModalPremGSP
(int a_duration
,mcenum_mode a_mode
- ,double a_bft_amt
- ,double a_specamt
+ ,currency a_bft_amt
+ ,currency a_specamt
) const;
- std::pair<double,double> GetModalPremMlyDedEx
+ std::pair<currency,currency> GetModalPremMlyDedEx
(int year
,mcenum_mode mode
- ,double specamt
- ,double termamt
+ ,currency specamt
+ ,currency termamt
) const;
- double GetListBillPremMlyDed
+ currency GetListBillPremMlyDed
(int year
,mcenum_mode mode
- ,double specamt
+ ,currency specamt
) const;
- std::pair<double,double> GetListBillPremMlyDedEx
+ std::pair<currency,currency> GetListBillPremMlyDedEx
(int year
,mcenum_mode mode
- ,double specamt
- ,double termamt
+ ,currency specamt
+ ,currency termamt
) const;
- double GetModalSpecAmtMax (double annualized_pmt) const;
- double GetModalSpecAmtTgt (double annualized_pmt) const;
- double GetModalSpecAmtMinNonMec(double annualized_pmt) const;
- double GetModalSpecAmtGLP (double annualized_pmt) const;
- double GetModalSpecAmtGSP (double annualized_pmt) const;
- double GetModalSpecAmtCorridor (double annualized_pmt) const;
- double GetModalSpecAmtSalary (int a_year) const;
+ currency GetModalSpecAmtMax (currency annualized_pmt) const;
+ currency GetModalSpecAmtTgt (currency annualized_pmt) const;
+ currency GetModalSpecAmtMinNonMec(currency annualized_pmt) const;
+ currency GetModalSpecAmtGLP (currency annualized_pmt) const;
+ currency GetModalSpecAmtGSP (currency annualized_pmt) const;
+ currency GetModalSpecAmtCorridor (currency annualized_pmt) const;
+ currency GetModalSpecAmtSalary (int a_year) const;
// Deprecated--used only by the antediluvian branch, which does
// not distinguish ee from er premium.
- double GetModalMaxSpecAmt
+ currency GetModalMaxSpecAmt
(mcenum_mode a_mode
- ,double a_pmt
+ ,currency a_pmt
) const;
// Deprecated--used only by the antediluvian branch, which does
// not distinguish ee from er premium.
- double GetModalTgtSpecAmt
+ currency GetModalTgtSpecAmt
(mcenum_mode a_mode
- ,double a_pmt
+ ,currency a_pmt
) const;
std::vector<double> GetTable
(std::string const& TableFile
@@ -294,7 +295,7 @@ class LMI_SO BasicValues
std::vector<double> const& GetBandedCoiRates
(mcenum_gen_basis rate_basis
- ,double a_specamt
+ ,currency a_specamt
) const;
// TODO ?? A priori, protected data is a defect.
@@ -310,13 +311,13 @@ class LMI_SO BasicValues
mcenum_defn_life_ins DefnLifeIns_;
mcenum_defn_material_change DefnMaterialChange_;
mcenum_dbopt_7702 Effective7702DboRop;
- double MaxNAAR;
+ currency MaxNAAR;
int EndtAge;
- double MinSpecAmt; // Antediluvian.
- double MinIssSpecAmt;
- double MinIssBaseSpecAmt;
- double MinRenlSpecAmt;
- double MinRenlBaseSpecAmt;
+ currency MinSpecAmt; // Antediluvian.
+ currency MinIssSpecAmt;
+ currency MinIssBaseSpecAmt;
+ currency MinRenlSpecAmt;
+ currency MinRenlBaseSpecAmt;
bool NoLapseDboLvlOnly;
bool NoLapseUnratedOnly;
bool OptChgCanIncrSA;
@@ -331,13 +332,13 @@ class LMI_SO BasicValues
int TermForcedConvDur;
bool TermIsDbFor7702;
bool TermIsDbFor7702A;
- double ExpPerKLimit;
+ double ExpPerKLimit; // CURRENCY !! may be infinity
oenum_modal_prem_type MinPremType;
oenum_modal_prem_type TgtPremType;
bool TgtPremFixedAtIssue;
- double TgtPremMonthlyPolFee;
- double CurrCoiTable0Limit;
- double CurrCoiTable1Limit;
+ currency TgtPremMonthlyPolFee;
+ double CurrCoiTable0Limit; // CURRENCY !! may be
infinity
+ double CurrCoiTable1Limit; // CURRENCY !! may be
infinity
e_actuarial_table_method CoiInforceReentry;
mcenum_anticipated_deduction MaxWDDed_;
double MaxWdGenAcctValMult;
@@ -355,11 +356,11 @@ class LMI_SO BasicValues
bool SurrChgOnDecr;
std::vector<double> FreeWDProportion;
- double AdbLimit;
- double WpLimit;
- double SpecAmtLoadLimit;
- double MinWD;
- double WDFee;
+ double AdbLimit; // CURRENCY !! may be infinity
+ double WpLimit; // CURRENCY !! may be infinity
+ double SpecAmtLoadLimit; // CURRENCY !! may be infinity
+ currency MinWD;
+ currency WDFee;
double WDFeeRate;
bool AllowChangeToDBO2;
@@ -381,7 +382,7 @@ class LMI_SO BasicValues
std::vector<double> MinPremIntSpread_;
- std::vector<double> TieredMEBands;
+ std::vector<currency> TieredMEBands;
std::vector<double> TieredMECharges;
private:
@@ -393,20 +394,20 @@ class LMI_SO BasicValues
double mly_ded_discount_factor(int year, mcenum_mode mode) const;
std::pair<double,double> approx_mly_ded
- (int year
- ,double specamt
+ (int year
+ ,currency specamt
) const;
std::pair<double,double> approx_mly_ded_ex
- (int year
- ,double specamt
- ,double termamt
+ (int year
+ ,currency specamt
+ ,currency termamt
) const;
- double GetModalPremMlyDed
+ currency GetModalPremMlyDed
(int year
,mcenum_mode mode
- ,double specamt
+ ,currency specamt
) const;
- double GetModalSpecAmtMlyDed(double annualized_pmt, mcenum_mode) const;
+ currency GetModalSpecAmtMlyDed(currency annualized_pmt, mcenum_mode) const;
std::vector<double> GetActuarialTable
(std::string const& TableFile
@@ -438,6 +439,9 @@ class LMI_SO BasicValues
std::vector<double> partial_mortality_tpx_;
std::vector<double> partial_mortality_lx_;
+ // This data member is not of type 'currency' because it merely
+ // stores an input parameter for the GPT server, and is used for
+ // no other purpose.
double InitialTargetPremium;
void Init7702();
diff --git a/basicvalues.cpp b/basicvalues.cpp
index 2ad33cd..9206717 100644
--- a/basicvalues.cpp
+++ b/basicvalues.cpp
@@ -137,20 +137,20 @@ double BasicValues::InvestmentManagementFee() const
//============================================================================
// IHS !! Simply calls the target-premium routine for now--see lmi.
-double BasicValues::GetModalMinPrem
+currency BasicValues::GetModalMinPrem
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const
{
return GetModalTgtPrem(a_year, a_mode, a_specamt);
}
//============================================================================
-double BasicValues::GetModalTgtPrem
+currency BasicValues::GetModalTgtPrem
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const
{
// IHS !! Simplistic. Ignores table ratings, flat extras, and
@@ -217,18 +217,18 @@ double BasicValues::GetModalTgtPrem
//============================================================================
// Simply calls the target-specamt routine for now.
-double BasicValues::GetModalMaxSpecAmt
+currency BasicValues::GetModalMaxSpecAmt
(mcenum_mode a_mode
- ,double a_pmt
+ ,currency a_pmt
) const
{
return GetModalTgtSpecAmt(a_mode, a_pmt);
}
//============================================================================
-double BasicValues::GetModalTgtSpecAmt
+currency BasicValues::GetModalTgtSpecAmt
(mcenum_mode a_mode
- ,double a_pmt
+ ,currency a_pmt
) const
{
// IHS !! Factor out the (defectively simplistic) code this
diff --git a/death_benefits.cpp b/death_benefits.cpp
index 062227f..89c90aa 100644
--- a/death_benefits.cpp
+++ b/death_benefits.cpp
@@ -56,7 +56,7 @@ death_benefits::death_benefits
}
//============================================================================
-void death_benefits::set_specamt(double z, int from_year, int to_year)
+void death_benefits::set_specamt(currency z, int from_year, int to_year)
{
#if 0
// Something like this would seem preferable, but it gives
@@ -75,7 +75,7 @@ void death_benefits::set_specamt(double z, int from_year, int
to_year)
}
//============================================================================
-void death_benefits::set_supplamt(double z, int from_year, int to_year)
+void death_benefits::set_supplamt(currency z, int from_year, int to_year)
{
#if 0
// Something like this would seem preferable, but it gives
diff --git a/death_benefits.hpp b/death_benefits.hpp
index ce5fd63..c0e1b0c 100644
--- a/death_benefits.hpp
+++ b/death_benefits.hpp
@@ -24,6 +24,7 @@
#include "config.hpp"
+#include "currency.hpp"
#include "mc_enum_type_enums.hpp"
#include "round_to.hpp"
@@ -41,12 +42,12 @@ class death_benefits final
);
~death_benefits() = default;
- void set_specamt (double z, int from_year, int to_year);
- void set_supplamt(double z, int from_year, int to_year);
+ void set_specamt (currency z, int from_year, int to_year);
+ void set_supplamt(currency z, int from_year, int to_year);
std::vector<mcenum_dbopt> const& dbopt () const;
- std::vector<double> const& specamt () const;
- std::vector<double> const& supplamt() const;
+ std::vector<currency> const& specamt () const;
+ std::vector<currency> const& supplamt() const;
private:
death_benefits(death_benefits const&) = delete;
@@ -57,8 +58,8 @@ class death_benefits final
round_to<double> round_specamt_;
std::vector<mcenum_dbopt> dbopt_ ;
- std::vector<double> specamt_ ;
- std::vector<double> supplamt_;
+ std::vector<currency> specamt_ ;
+ std::vector<currency> supplamt_;
};
inline std::vector<mcenum_dbopt> const& death_benefits::dbopt() const
@@ -66,12 +67,12 @@ inline std::vector<mcenum_dbopt> const&
death_benefits::dbopt() const
return dbopt_;
}
-inline std::vector<double> const& death_benefits::specamt() const
+inline std::vector<currency> const& death_benefits::specamt() const
{
return specamt_;
}
-inline std::vector<double> const& death_benefits::supplamt() const
+inline std::vector<currency> const& death_benefits::supplamt() const
{
return supplamt_;
}
diff --git a/gpt_specamt.cpp b/gpt_specamt.cpp
index a134111..d00b77e 100644
--- a/gpt_specamt.cpp
+++ b/gpt_specamt.cpp
@@ -28,10 +28,10 @@
#include "safely_dereference_as.hpp"
#include "zero.hpp"
-double gpt_specamt::CalculateGLPSpecAmt
+currency gpt_specamt::CalculateGLPSpecAmt
(BasicValues const& a_Values
,int a_Duration
- ,double a_Premium
+ ,currency a_Premium
,mcenum_dbopt_7702 a_DBOpt
)
{
@@ -46,10 +46,10 @@ double gpt_specamt::CalculateGLPSpecAmt
);
}
-double gpt_specamt::CalculateGSPSpecAmt
+currency gpt_specamt::CalculateGSPSpecAmt
(BasicValues const& a_Values
,int a_Duration
- ,double a_Premium
+ ,currency a_Premium
)
{
Irc7702 const& z(safely_dereference_as<Irc7702>(a_Values.Irc7702_.get()));
@@ -70,10 +70,10 @@ class FindSpecAmt
Irc7702 const& Irc7702_;
EIOBasis const EIOBasis_;
int const Duration;
- double const Premium;
+ double const Premium; // CURRENCY !! not currency?
double const NetPmtFactorTgt;
double const NetPmtFactorExc;
- double SpecAmt;
+ currency SpecAmt;
public:
FindSpecAmt
@@ -81,7 +81,7 @@ class FindSpecAmt
,Irc7702 const& a_IRC7702
,EIOBasis a_EIOBasis
,int a_Duration
- ,double a_Premium
+ ,double a_Premium // CURRENCY !! not currency?
,double a_NetPmtFactorTgt
,double a_NetPmtFactorExc
)
@@ -95,6 +95,7 @@ class FindSpecAmt
,SpecAmt {0.0}
{
}
+ // CURRENCY !! decimal_root() expects this; but see 'ihs_avsolve.cpp'.
double operator()(double a_Trial)
{
SpecAmt = a_Trial;
@@ -112,7 +113,7 @@ class FindSpecAmt
- Premium
;
}
- double Get()
+ currency Get()
{
return SpecAmt;
}
@@ -130,11 +131,11 @@ class FindSpecAmt
/// because it is typically used to set an input parameter, and
/// specamt is such a parameter whereas DB is not.
-double gpt_specamt::CalculateSpecAmt
+currency gpt_specamt::CalculateSpecAmt
(BasicValues const& a_Values
,EIOBasis a_EIOBasis
,int a_Duration
- ,double a_Premium
+ ,currency a_Premium
,double a_NetPmtFactorTgt
,double a_NetPmtFactorExc
)
diff --git a/gpt_specamt.hpp b/gpt_specamt.hpp
index 5568879..d94c7ca 100644
--- a/gpt_specamt.hpp
+++ b/gpt_specamt.hpp
@@ -24,6 +24,7 @@
#include "config.hpp"
+#include "currency.hpp"
#include "ihs_irc7702.hpp" // Irc7702::EIOBasis
#include "mc_enum_type_enums.hpp" // mcenum_dbopt_7702
@@ -53,24 +54,24 @@ class gpt_specamt
typedef Irc7702::EIOBasis EIOBasis;
public:
- static double CalculateGLPSpecAmt
+ static currency CalculateGLPSpecAmt
(BasicValues const& a_Values
,int a_Duration
- ,double a_Premium
+ ,currency a_Premium
,mcenum_dbopt_7702 a_DBOpt
);
- static double CalculateGSPSpecAmt
+ static currency CalculateGSPSpecAmt
(BasicValues const& a_Values
,int a_Duration
- ,double a_Premium
+ ,currency a_Premium
);
private:
- static double CalculateSpecAmt
+ static currency CalculateSpecAmt
(BasicValues const& a_Values
,Irc7702::EIOBasis a_EIOBasis
,int a_Duration
- ,double a_Premium
+ ,currency a_Premium
,double a_NetPmtFactorTgt
,double a_NetPmtFactorExc
);
diff --git a/ihs_acctval.cpp b/ihs_acctval.cpp
index 4bf92bf..12e6e87 100644
--- a/ihs_acctval.cpp
+++ b/ihs_acctval.cpp
@@ -140,21 +140,21 @@ AccountValue::AccountValue(Input const& input)
/// Specified amount (disregarding any term or "supplemental" amount).
-double AccountValue::base_specamt(int year) const
+currency AccountValue::base_specamt(int year) const
{
return InvariantValues().SpecAmt[year];
}
/// Specified amount of term rider.
-double AccountValue::term_specamt(int year) const
+currency AccountValue::term_specamt(int year) const
{
return InvariantValues().TermSpecAmt[year];
}
/// Specified amount for 7702 (not 7702A).
-double AccountValue::specamt_for_7702(int year) const
+currency AccountValue::specamt_for_7702(int year) const
{
return
base_specamt(year)
@@ -164,7 +164,7 @@ double AccountValue::specamt_for_7702(int year) const
/// Specified amount for 7702A (not 7702).
-double AccountValue::specamt_for_7702A(int year) const
+currency AccountValue::specamt_for_7702A(int year) const
{
return
base_specamt(year)
@@ -676,7 +676,7 @@ void AccountValue::SetInitialValues()
//============================================================================
// Process monthly transactions up to but excluding interest credit
-double AccountValue::IncrementBOM
+currency AccountValue::IncrementBOM
(int year
,int month
,double a_case_k_factor
@@ -735,10 +735,10 @@ double AccountValue::IncrementBOM
//============================================================================
// Credit interest and process all subsequent monthly transactions
void AccountValue::IncrementEOM
- (int year
- ,int month
- ,double assets_post_bom
- ,double cum_pmts_post_bom
+ (int year
+ ,int month
+ ,currency assets_post_bom
+ ,currency cum_pmts_post_bom
)
{
if(ItLapsed || BasicValues::GetLength() <= Year)
@@ -999,7 +999,7 @@ void AccountValue::set_modal_min_premium()
///
/// SOMEDAY !! Table support and UL model reg formulas should be added.
-double AccountValue::SurrChg() const
+currency AccountValue::SurrChg() const
{
LMI_ASSERT(0.0 <= SurrChg_[Year]);
// For the nonce, CSVBoost() is netted against surrender charge.
@@ -1012,7 +1012,7 @@ double AccountValue::SurrChg() const
///
/// Probably the input field should be expunged.
-double AccountValue::CSVBoost() const
+currency AccountValue::CSVBoost() const
{
double const z =
CashValueEnhMult[Year]
@@ -1424,8 +1424,13 @@ void AccountValue::SetAnnualInvariants()
YearsDacTaxLoadRate = Loads_->dac_tax_load ()[Year];
}
-//============================================================================
-double AccountValue::GetSepAcctAssetsInforce() const
+/// Separate-account assets, after deductions, times survivorship.
+///
+/// Returns a currency value because assets are ordinarily thought of
+/// as currency, and because this function is used only where currency
+/// is wanted--even though it's multiplied by a survivorship factor.
+
+currency AccountValue::GetSepAcctAssetsInforce() const
{
if(ItLapsed || BasicValues::GetLength() <= Year)
{
diff --git a/ihs_avmly.cpp b/ihs_avmly.cpp
index 1f51601..479bab4 100644
--- a/ihs_avmly.cpp
+++ b/ihs_avmly.cpp
@@ -261,7 +261,7 @@ void AccountValue::DoMonthCR()
//============================================================================
// Apportion all payments among accounts.
-void AccountValue::process_payment(double payment)
+void AccountValue::process_payment(currency payment)
{
// Apply ee and er net payments according to database rules.
// Net payments were already aggregated, then split between
@@ -331,7 +331,7 @@ void AccountValue::process_payment(double payment)
//============================================================================
// Prorate increments to account value between separate- and general-account
// portions of unloaned account value according to input allocations.
-void AccountValue::IncrementAVProportionally(double increment)
+void AccountValue::IncrementAVProportionally(currency increment)
{
increment = round_minutiae()(increment);
double genacct_increment = increment * GenAcctPaymentAllocation;
@@ -343,7 +343,7 @@ void AccountValue::IncrementAVProportionally(double
increment)
//============================================================================
// Apply increments to account value to the preferred account.
void AccountValue::IncrementAVPreferentially
- (double increment
+ (currency increment
,oenum_increment_account_preference preferred_account
)
{
@@ -365,7 +365,7 @@ void AccountValue::IncrementAVPreferentially
/// Apportion all charges to be deducted from account value among
/// accounts.
-void AccountValue::process_deduction(double decrement)
+void AccountValue::process_deduction(currency decrement)
{
switch(deduction_method)
{
@@ -384,7 +384,7 @@ void AccountValue::process_deduction(double decrement)
/// Apportion all distributions from account value among accounts.
-void AccountValue::process_distribution(double decrement)
+void AccountValue::process_distribution(currency decrement)
{
switch(distribution_method)
{
@@ -413,7 +413,7 @@ void AccountValue::process_distribution(double decrement)
/// Otherwise, unloaned account value might have a minuscule negative
/// value due to catastrophic cancellation, improperly causing lapse.
-void AccountValue::DecrementAVProportionally(double decrement)
+void AccountValue::DecrementAVProportionally(currency decrement)
{
decrement = round_minutiae()(decrement);
@@ -477,7 +477,7 @@ void AccountValue::DecrementAVProportionally(double
decrement)
/// value due to catastrophic cancellation, improperly causing lapse.
void AccountValue::DecrementAVProgressively
- (double decrement
+ (currency decrement
,oenum_increment_account_preference preferred_account
)
{
@@ -622,7 +622,7 @@ void AccountValue::TxExch1035()
}
//============================================================================
-double AccountValue::CashValueFor7702() const
+currency AccountValue::CashValueFor7702() const
{
return std::max
(HoneymoonValue
@@ -653,9 +653,9 @@ double AccountValue::ActualMonthlyRate(double monthly_rate)
const
//============================================================================
// Rounded interest increment.
-double AccountValue::InterestCredited
- (double principal
- ,double monthly_rate
+currency AccountValue::InterestCredited
+ (currency principal
+ ,double monthly_rate
) const
{
return round_interest_credit()(principal *
ActualMonthlyRate(monthly_rate));
@@ -686,7 +686,7 @@ int AccountValue::MonthsToNextModalPmtDate() const
/// Argument 'term_rider' indicates whether a term rider is to be
/// taken into account, as that affects the base-policy minimum.
-double AccountValue::minimum_specified_amount(bool issuing_now, bool
term_rider) const
+currency AccountValue::minimum_specified_amount(bool issuing_now, bool
term_rider) const
{
return
issuing_now
@@ -699,7 +699,7 @@ double AccountValue::minimum_specified_amount(bool
issuing_now, bool term_rider)
// All changes to SA must be handled here.
// Proportionately reduce base and term SA if term rider present.
// Make sure ActualSpecAmt is never less than minimum specamt.
-void AccountValue::ChangeSpecAmtBy(double delta)
+void AccountValue::ChangeSpecAmtBy(currency delta)
{
delta = round_specamt()(delta);
double term_proportion = 0.0;
@@ -793,7 +793,7 @@ void AccountValue::ChangeSpecAmtBy(double delta)
TxSetDeathBft();
}
-void AccountValue::ChangeSupplAmtBy(double delta)
+void AccountValue::ChangeSupplAmtBy(currency delta)
{
delta = round_specamt()(delta);
TermSpecAmt += delta;
@@ -1239,9 +1239,14 @@ void AccountValue::TxAscertainDesiredPayment()
LMI_ASSERT(materially_equal(GrossPmts[Month], EeGrossPmts[Month] +
ErGrossPmts[Month]));
}
-//============================================================================
-// TAXATION !! Should this be called for gpt? or, if it's called,
-// should it assert that it has no effect?
+/// Limit payment (e.g., to the non-MEC maximum).
+///
+/// The limit argument is of type double because the taxation code may
+/// return DBL_MAX. CURRENCY !! Can currency work with such values?
+///
+/// TAXATION !! Should this be called for gpt? or, if it's called,
+/// should it assert that it has no effect?
+
void AccountValue::TxLimitPayment(double a_maxpmt)
{
// Subtract premium load from gross premium yielding net premium.
@@ -1299,8 +1304,8 @@ void AccountValue::TxLimitPayment(double a_maxpmt)
//============================================================================
void AccountValue::TxRecognizePaymentFor7702A
- (double a_pmt
- ,bool a_this_payment_is_unnecessary
+ (currency a_pmt
+ ,bool a_this_payment_is_unnecessary
)
{
if(0.0 == a_pmt)
@@ -1341,7 +1346,7 @@ void AccountValue::TxRecognizePaymentFor7702A
}
//============================================================================
-void AccountValue::TxAcceptPayment(double a_pmt)
+void AccountValue::TxAcceptPayment(currency a_pmt)
{
if(0.0 == a_pmt)
{
@@ -1403,9 +1408,9 @@ void AccountValue::TxAcceptPayment(double a_pmt)
/// calculation doesn't require too many adjustments, in particular
/// when tiered premium tax is passed through as a load.
-double AccountValue::GetPremLoad
- (double a_pmt
- ,double a_portion_exempt_from_premium_tax
+currency AccountValue::GetPremLoad
+ (currency a_pmt
+ ,currency a_portion_exempt_from_premium_tax
)
{
double excess_portion;
@@ -1470,7 +1475,7 @@ double AccountValue::GetPremLoad
}
//============================================================================
-double AccountValue::GetRefundableSalesLoad() const
+currency AccountValue::GetRefundableSalesLoad() const
{
return CumulativeSalesLoad * YearsSalesLoadRefundRate;
#if 0
@@ -2025,7 +2030,7 @@ void AccountValue::TxTakeSepAcctLoad()
//============================================================================
// When the M&E charge depends on each month's case total assets, the
// interest rate is no longer an annual invariant. Set it monthly here.
-void AccountValue::ApplyDynamicMandE(double assets)
+void AccountValue::ApplyDynamicMandE(currency assets)
{
if(!MandEIsDynamic)
{
@@ -2254,7 +2259,7 @@ void AccountValue::TxLoanInt()
// actual future deductions--particularly in the month of issue, when
// it is zero.
//
-double AccountValue::anticipated_deduction
+currency AccountValue::anticipated_deduction
(mcenum_anticipated_deduction method)
{
switch(method)
diff --git a/ihs_avsolve.cpp b/ihs_avsolve.cpp
index db77f90..b508b89 100644
--- a/ihs_avsolve.cpp
+++ b/ihs_avsolve.cpp
@@ -49,7 +49,7 @@ namespace
{
// TODO ?? Shouldn't this be a typedef for a SolveHelper member?
// As it stands, this would seem not to be reentrant.
- void (AccountValue::*solve_set_fn)(double);
+ void (AccountValue::*solve_set_fn)(currency);
} // Unnamed namespace.
class SolveHelper
@@ -60,6 +60,12 @@ class SolveHelper
:av {a_av}
{
}
+ // CURRENCY !! decimal_root() invokes this thus:
+ // static_cast<double>(function(double));
+ // so
+ // double function(double)
+ // is the appropriate signature here. Someday it might make sense
+ // to modify decimal_root to work with currency types directly.
double operator()(double a_CandidateValue)
{
return av.SolveTest(a_CandidateValue);
@@ -160,7 +166,7 @@ class SolveHelper
/// "Section 7B(2) does not preclude the illustrating of premiums
/// that exceed the guideline premiums in Section 7702 of the IRC."
-double AccountValue::SolveTest(double a_CandidateValue)
+currency AccountValue::SolveTest(currency a_CandidateValue)
{
(this->*solve_set_fn)(a_CandidateValue);
@@ -243,7 +249,7 @@ double AccountValue::SolveTest(double a_CandidateValue)
}
//============================================================================
-void AccountValue::SolveSetSpecAmt(double a_CandidateValue)
+void AccountValue::SolveSetSpecAmt(currency a_CandidateValue)
{
// TODO ?? Does this change the surrchg when specamt changes?
DeathBfts_->set_specamt
@@ -254,31 +260,31 @@ void AccountValue::SolveSetSpecAmt(double
a_CandidateValue)
}
//============================================================================
-void AccountValue::SolveSetEePrem(double a_CandidateValue)
+void AccountValue::SolveSetEePrem(currency a_CandidateValue)
{
Outlay_->set_ee_modal_premiums(a_CandidateValue, SolveBeginYear_,
SolveEndYear_);
}
//============================================================================
-void AccountValue::SolveSetErPrem(double a_CandidateValue)
+void AccountValue::SolveSetErPrem(currency a_CandidateValue)
{
Outlay_->set_er_modal_premiums(a_CandidateValue, SolveBeginYear_,
SolveEndYear_);
}
//============================================================================
-void AccountValue::SolveSetLoan(double a_CandidateValue)
+void AccountValue::SolveSetLoan(currency a_CandidateValue)
{
Outlay_->set_new_cash_loans(a_CandidateValue, SolveBeginYear_,
SolveEndYear_);
}
//============================================================================
-void AccountValue::SolveSetWD(double a_CandidateValue)
+void AccountValue::SolveSetWD(currency a_CandidateValue)
{
Outlay_->set_withdrawals(a_CandidateValue, SolveBeginYear_, SolveEndYear_);
}
//============================================================================
-double AccountValue::SolveGuarPremium()
+currency AccountValue::SolveGuarPremium()
{
// Store original er premiums for later restoration.
std::vector<double> stored = Outlay_->er_modal_premiums();
@@ -310,12 +316,12 @@ double AccountValue::SolveGuarPremium()
}
//============================================================================
-double AccountValue::Solve
+currency AccountValue::Solve
(mcenum_solve_type a_SolveType
,int a_SolveBeginYear
,int a_SolveEndYear
,mcenum_solve_target a_SolveTarget
- ,double a_SolveTargetCsv
+ ,currency a_SolveTargetCsv
,int a_SolveTargetYear
,mcenum_gen_basis a_SolveGenBasis
,mcenum_sep_basis a_SolveSepBasis
diff --git a/ihs_avstrtgy.cpp b/ihs_avstrtgy.cpp
index 96dce1a..32aee10 100644
--- a/ihs_avstrtgy.cpp
+++ b/ihs_avstrtgy.cpp
@@ -56,10 +56,10 @@
///
/// No minimum is imposed here; see PerformSpecAmtStrategy().
-double AccountValue::CalculateSpecAmtFromStrategy
+currency AccountValue::CalculateSpecAmtFromStrategy
(int actual_year
,int reference_year
- ,double explicit_value
+ ,currency explicit_value
,mcenum_sa_strategy strategy
) const
{
@@ -182,12 +182,12 @@ void AccountValue::PerformSupplAmtStrategy()
/// Set payment according to selected strategy in a non-solve year.
-double AccountValue::DoPerformPmtStrategy
+currency AccountValue::DoPerformPmtStrategy
(mcenum_solve_type a_SolveForWhichPrem
,mcenum_mode a_CurrentMode
,mcenum_mode a_InitialMode
,double a_TblMult
- ,std::vector<double> const& a_PmtVector
+ ,std::vector<currency> const& a_PmtVector
,std::vector<mcenum_pmt_strategy> const& a_StrategyVector
) const
{
@@ -304,7 +304,7 @@ double AccountValue::DoPerformPmtStrategy
/// Set employee payment according to selected strategy.
-double AccountValue::PerformEePmtStrategy() const
+currency AccountValue::PerformEePmtStrategy() const
{
return DoPerformPmtStrategy
(mce_solve_ee_prem
@@ -318,7 +318,7 @@ double AccountValue::PerformEePmtStrategy() const
/// Set employer payment according to selected strategy.
-double AccountValue::PerformErPmtStrategy() const
+currency AccountValue::PerformErPmtStrategy() const
{
return DoPerformPmtStrategy
(mce_solve_er_prem
diff --git a/ihs_basicval.cpp b/ihs_basicval.cpp
index 2452d03..47ab721 100644
--- a/ihs_basicval.cpp
+++ b/ihs_basicval.cpp
@@ -541,7 +541,7 @@ void BasicValues::Init7702A()
/// Public function used for GPT specamt calculation.
-double BasicValues::GetAnnualTgtPrem(int a_year, double a_specamt) const
+currency BasicValues::GetAnnualTgtPrem(int a_year, currency a_specamt) const
{
return GetModalTgtPrem(a_year, mce_annual, a_specamt);
}
@@ -851,10 +851,10 @@ double BasicValues::GetPartMortQ(int a_year) const
/// value would otherwise be negative), or
/// - keeps account value nonnegative (preventing lapse directly).
-double BasicValues::GetModalMinPrem
+currency BasicValues::GetModalMinPrem
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const
{
switch(MinPremType)
@@ -871,10 +871,10 @@ double BasicValues::GetModalMinPrem
/// Ascertain modal payment for a target-premium strategy.
-double BasicValues::GetModalTgtPrem
+currency BasicValues::GetModalTgtPrem
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const
{
int const target_year = TgtPremFixedAtIssue ? 0 : a_year;
@@ -897,10 +897,10 @@ double BasicValues::GetModalTgtPrem
/// and specified amount. Thus, arguments should represent initial
/// premium and mode.
-double BasicValues::GetModalPremMaxNonMec
+currency BasicValues::GetModalPremMaxNonMec
(int // a_year // Unused.
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const
{
// TAXATION !! No table available if 7PP calculated from first principles.
@@ -915,10 +915,10 @@ double BasicValues::GetModalPremMaxNonMec
/// the initial specified amount may also be fixed at issue, but that
/// choice is left to the caller.
-double BasicValues::GetModalPremMinFromTable
+currency BasicValues::GetModalPremMinFromTable
(int // a_year // Unused.
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const
{
return round_max_premium()
@@ -953,10 +953,10 @@ double BasicValues::GetModalPremMinFromTable
/// asserted to be zero--upstream, so that it'll signal an error even
/// if a target strategy isn't used.
-double BasicValues::GetModalPremTgtFromTable
+currency BasicValues::GetModalPremTgtFromTable
(int // a_year // Unused.
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const
{
return round_max_premium()
@@ -972,10 +972,10 @@ double BasicValues::GetModalPremTgtFromTable
/// Calculate premium using a tabular proxy for group insurance.
-double BasicValues::GetModalPremProxyTable
+currency BasicValues::GetModalPremProxyTable
(int a_year
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
,double a_table_multiplier
) const
{
@@ -994,10 +994,10 @@ double BasicValues::GetModalPremProxyTable
/// strategy makes sense only at issue. Thus, arguments should
/// represent initial specified amount and mode.
-double BasicValues::GetModalPremCorridor
+currency BasicValues::GetModalPremCorridor
(int // a_year // Unused.
,mcenum_mode a_mode
- ,double a_specamt
+ ,currency a_specamt
) const
{
double temp = GetCorridorFactor()[0];
@@ -1005,11 +1005,11 @@ double BasicValues::GetModalPremCorridor
}
//============================================================================
-double BasicValues::GetModalPremGLP
+currency BasicValues::GetModalPremGLP
(int a_duration
,mcenum_mode a_mode
- ,double a_bft_amt
- ,double a_specamt
+ ,currency a_bft_amt
+ ,currency a_specamt
) const
{
// TAXATION !! Use GetAnnualTgtPrem() to get target here if needed
@@ -1031,11 +1031,11 @@ double BasicValues::GetModalPremGLP
}
//============================================================================
-double BasicValues::GetModalPremGSP
+currency BasicValues::GetModalPremGSP
(int a_duration
,mcenum_mode a_mode
- ,double a_bft_amt
- ,double a_specamt
+ ,currency a_bft_amt
+ ,currency a_specamt
) const
{
double z = Irc7702_->CalculateGSP
@@ -1122,10 +1122,12 @@ double BasicValues::mly_ded_discount_factor(int year,
mcenum_mode mode) const
/// employer typically pays the approximate monthly deductions, but
/// may also be used with any UL product when such a payment pattern
/// is desired.
+///
+/// Returns a pair of deliberately unrounded doubles.
std::pair<double,double> BasicValues::approx_mly_ded
- (int year
- ,double specamt
+ (int year
+ ,currency specamt
) const
{
double mly_ded = specamt * DBDiscountRate[year];
@@ -1200,11 +1202,13 @@ std::pair<double,double> BasicValues::approx_mly_ded
/// (e.g., a fee to offset underwriting costs for private placements)
/// are extraordinary, and occur only on products for which a split
/// between ee and er would not be wanted.
+///
+/// Returns a pair of deliberately unrounded doubles.
std::pair<double,double> BasicValues::approx_mly_ded_ex
- (int year
- ,double specamt
- ,double termamt
+ (int year
+ ,currency specamt
+ ,currency termamt
) const
{
if(0.0 != Loads_->annual_policy_fee(mce_gen_curr)[year])
@@ -1279,10 +1283,10 @@ std::pair<double,double> BasicValues::approx_mly_ded_ex
/// Determine an approximate "pay as you go" modal premium.
-double BasicValues::GetModalPremMlyDed
+currency BasicValues::GetModalPremMlyDed
(int year
,mcenum_mode mode
- ,double specamt
+ ,currency specamt
) const
{
auto const deductions = approx_mly_ded(year, specamt);
@@ -1295,11 +1299,11 @@ double BasicValues::GetModalPremMlyDed
/// Determine approximate ee and er "pay as you go" modal premiums.
-std::pair<double,double> BasicValues::GetModalPremMlyDedEx
+std::pair<currency,currency> BasicValues::GetModalPremMlyDedEx
(int year
,mcenum_mode mode
- ,double specamt
- ,double termamt
+ ,currency specamt
+ ,currency termamt
) const
{
auto const deductions = approx_mly_ded_ex(year, specamt, termamt);
@@ -1330,10 +1334,10 @@ std::pair<double,double>
BasicValues::GetModalPremMlyDedEx
/// are extraordinary, and occur only on products for which list bills
/// would not be wanted.
-double BasicValues::GetListBillPremMlyDed
+currency BasicValues::GetListBillPremMlyDed
(int year
,mcenum_mode mode
- ,double specamt
+ ,currency specamt
) const
{
double const p0 = approx_mly_ded(year, specamt).second;
@@ -1354,11 +1358,11 @@ double BasicValues::GetListBillPremMlyDed
return round_min_premium()(z);
}
-std::pair<double,double> BasicValues::GetListBillPremMlyDedEx
+std::pair<currency,currency> BasicValues::GetListBillPremMlyDedEx
(int year
,mcenum_mode mode
- ,double specamt
- ,double termamt
+ ,currency specamt
+ ,currency termamt
) const
{
auto const p0 = approx_mly_ded_ex(year, specamt, termamt);
@@ -1390,7 +1394,7 @@ std::pair<double,double>
BasicValues::GetListBillPremMlyDedEx
);
}
-double BasicValues::GetModalSpecAmtMax(double annualized_pmt) const
+currency BasicValues::GetModalSpecAmtMax(currency annualized_pmt) const
{
switch(MinPremType)
{
@@ -1414,7 +1418,7 @@ double BasicValues::GetModalSpecAmtMax(double
annualized_pmt) const
/// duration. It's taken to include 'TgtPremMonthlyPolFee', to make
/// this function the inverse of GetModalPremTgtFromTable(), q.v.
-double BasicValues::GetModalSpecAmtTgt(double annualized_pmt) const
+currency BasicValues::GetModalSpecAmtTgt(currency annualized_pmt) const
{
switch(TgtPremType)
{
@@ -1438,21 +1442,21 @@ double BasicValues::GetModalSpecAmtTgt(double
annualized_pmt) const
/// changes dramatically complicate the relationship between premium
/// and specified amount.
-double BasicValues::GetModalSpecAmtMinNonMec(double annualized_pmt) const
+currency BasicValues::GetModalSpecAmtMinNonMec(currency annualized_pmt) const
{
// TAXATION !! No table available if 7PP calculated from first principles.
return round_min_specamt()(annualized_pmt /
MortalityRates_->SevenPayRates()[0]);
}
//============================================================================
-double BasicValues::GetModalSpecAmtGLP(double annualized_pmt) const
+currency BasicValues::GetModalSpecAmtGLP(currency annualized_pmt) const
{
mcenum_dbopt_7702 const z = effective_dbopt_7702(DeathBfts_->dbopt()[0],
Effective7702DboRop);
return gpt_specamt::CalculateGLPSpecAmt(*this, 0, annualized_pmt, z);
}
//============================================================================
-double BasicValues::GetModalSpecAmtGSP(double annualized_pmt) const
+currency BasicValues::GetModalSpecAmtGSP(currency annualized_pmt) const
{
return gpt_specamt::CalculateGSPSpecAmt(*this, 0, annualized_pmt);
}
@@ -1494,7 +1498,7 @@ double BasicValues::GetModalSpecAmtGSP(double
annualized_pmt) const
/// integral cents, this implementation cannot guarantee to give the
/// desired answer in every case.
-double BasicValues::GetModalSpecAmtCorridor(double annualized_pmt) const
+currency BasicValues::GetModalSpecAmtCorridor(currency annualized_pmt) const
{
int const k = round_corridor_factor().decimals();
double const s = nonstd::power(10, k);
@@ -1509,7 +1513,7 @@ double BasicValues::GetModalSpecAmtCorridor(double
annualized_pmt) const
/// sufficiently large, then specamt would be negative, which cannot
/// make any sense.
-double BasicValues::GetModalSpecAmtSalary(int a_year) const
+currency BasicValues::GetModalSpecAmtSalary(int a_year) const
{
double z =
yare_input_.ProjectedSalary[a_year]
@@ -1530,7 +1534,7 @@ double BasicValues::GetModalSpecAmtSalary(int a_year)
const
/// calling this function elicits an error message. SOMEDAY !! It
/// would be better to disable this strategy in the GUI.
-double BasicValues::GetModalSpecAmtMlyDed(double, mcenum_mode) const
+currency BasicValues::GetModalSpecAmtMlyDed(currency, mcenum_mode) const
{
alarum()
<< "No maximum specified amount is defined for this product."
@@ -1547,7 +1551,7 @@ double BasicValues::GetModalSpecAmtMlyDed(double,
mcenum_mode) const
std::vector<double> const& BasicValues::GetBandedCoiRates
(mcenum_gen_basis rate_basis
- ,double a_specamt
+ ,currency a_specamt
) const
{
if(UseUnusualCOIBanding && mce_gen_guar != rate_basis)
diff --git a/loads.hpp b/loads.hpp
index 44d85d2..8e99166 100644
--- a/loads.hpp
+++ b/loads.hpp
@@ -24,6 +24,7 @@
#include "config.hpp"
+#include "currency.hpp"
#include "mc_enum_type_enums.hpp"
#include <vector>
@@ -49,16 +50,16 @@ class Loads
// termination, the refund applies only to the sales load.
std::vector<double> const& refundable_sales_load_proportion() const;
- std::vector<double> const& monthly_policy_fee (mcenum_gen_basis) const;
- std::vector<double> const& annual_policy_fee (mcenum_gen_basis) const;
- std::vector<double> const& specified_amount_load (mcenum_gen_basis) const;
- std::vector<double> const& separate_account_load (mcenum_gen_basis) const;
- std::vector<double> const& target_premium_load (mcenum_gen_basis) const;
- std::vector<double> const& excess_premium_load (mcenum_gen_basis) const;
- std::vector<double> const& target_sales_load (mcenum_gen_basis) const;
- std::vector<double> const& excess_sales_load (mcenum_gen_basis) const;
- std::vector<double> const& target_total_load (mcenum_gen_basis) const;
- std::vector<double> const& excess_total_load (mcenum_gen_basis) const;
+ std::vector<currency> const& monthly_policy_fee (mcenum_gen_basis)
const;
+ std::vector<currency> const& annual_policy_fee (mcenum_gen_basis)
const;
+ std::vector<double> const& specified_amount_load (mcenum_gen_basis)
const;
+ std::vector<double> const& separate_account_load (mcenum_gen_basis)
const;
+ std::vector<double> const& target_premium_load (mcenum_gen_basis)
const;
+ std::vector<double> const& excess_premium_load (mcenum_gen_basis)
const;
+ std::vector<double> const& target_sales_load (mcenum_gen_basis)
const;
+ std::vector<double> const& excess_sales_load (mcenum_gen_basis)
const;
+ std::vector<double> const& target_total_load (mcenum_gen_basis)
const;
+ std::vector<double> const& excess_total_load (mcenum_gen_basis)
const;
std::vector<double> const& premium_tax_load () const;
std::vector<double> const& amortized_premium_tax_load () const;
@@ -82,16 +83,16 @@ class Loads
std::vector<double> refundable_sales_load_proportion_;
- std::vector<std::vector<double>> monthly_policy_fee_;
- std::vector<std::vector<double>> annual_policy_fee_;
- std::vector<std::vector<double>> specified_amount_load_;
- std::vector<std::vector<double>> separate_account_load_;
- std::vector<std::vector<double>> target_premium_load_;
- std::vector<std::vector<double>> excess_premium_load_;
- std::vector<std::vector<double>> target_sales_load_;
- std::vector<std::vector<double>> excess_sales_load_;
- std::vector<std::vector<double>> target_total_load_;
- std::vector<std::vector<double>> excess_total_load_;
+ std::vector<std::vector<currency>> monthly_policy_fee_;
+ std::vector<std::vector<currency>> annual_policy_fee_;
+ std::vector<std::vector<double>> specified_amount_load_;
+ std::vector<std::vector<double>> separate_account_load_;
+ std::vector<std::vector<double>> target_premium_load_;
+ std::vector<std::vector<double>> excess_premium_load_;
+ std::vector<std::vector<double>> target_sales_load_;
+ std::vector<std::vector<double>> excess_sales_load_;
+ std::vector<std::vector<double>> target_total_load_;
+ std::vector<std::vector<double>> excess_total_load_;
std::vector<double> premium_tax_load_;
std::vector<double> amortized_premium_tax_load_;
@@ -111,13 +112,13 @@ Loads::refundable_sales_load_proportion() const
return refundable_sales_load_proportion_;
}
-inline std::vector<double> const&
+inline std::vector<currency> const&
Loads::monthly_policy_fee(mcenum_gen_basis b) const
{
return monthly_policy_fee_[b];
}
-inline std::vector<double> const&
+inline std::vector<currency> const&
Loads::annual_policy_fee(mcenum_gen_basis b) const
{
return annual_policy_fee_[b];
diff --git a/loads_impl.hpp b/loads_impl.hpp
index 82f42a9..86ea89f 100644
--- a/loads_impl.hpp
+++ b/loads_impl.hpp
@@ -24,6 +24,7 @@
#include "config.hpp"
+#include "currency.hpp"
#include "oecumenic_enumerations.hpp"
#include "round_to.hpp"
@@ -62,8 +63,16 @@ class product_database;
/// charge--it is expressed annually, converted to monthly in the
/// implementation, and then must be rounded.
///
-/// round_minutiae_: Rounding function-object used for policy fees,
-/// which generally are an integral number of cents.
+/// round_minutiae_: Rounding function-object used for policy fees.
+/// No known product specifies any policy fee in fractional cents.
+/// However, if the monthly policy fee is $3.25 (current) and $5.00
+/// (guaranteed), the midpoint mustn't be $4.125, because subtracting
+/// that from the account value would make it a non-integral number
+/// of cents. An argument could be made for using a gross-premium
+/// rounding rule instead, reasoning that a policy fee ought to be
+/// independently payable, but the minutiae rule is likely to specify
+/// finer (or no different) rounding, which seems better for the
+/// midpoint case.
///
/// VectorExtraCompLoad_: Input extra load per dollar of premium.
///
@@ -85,23 +94,23 @@ class product_database;
struct load_details
{
load_details
- (int length
- ,bool AmortizePremLoad
- ,double premium_tax_load
- ,double maximum_premium_tax_load_rate
- ,double minimum_premium_tax_load_rate
- ,double premium_tax_rate
- ,double premium_tax_amortization_rate
- ,int premium_tax_amortization_period
- ,oenum_asset_charge_type asset_charge_type
- ,bool NeedMidpointRates
- ,round_to<double> const& round_interest_rate
- ,round_to<double> const& round_minutiae
- ,std::vector<double> const& VectorExtraCompLoad
- ,std::vector<double> const& VectorExtraAssetComp
- ,std::vector<double> const& VectorExtraPolFee
- ,std::vector<double> const& TabularGuarSpecAmtLoad
- ,std::vector<double> const& TabularCurrSpecAmtLoad
+ (int length
+ ,bool AmortizePremLoad
+ ,double premium_tax_load
+ ,double maximum_premium_tax_load_rate
+ ,double minimum_premium_tax_load_rate
+ ,double premium_tax_rate
+ ,double premium_tax_amortization_rate
+ ,int premium_tax_amortization_period
+ ,oenum_asset_charge_type asset_charge_type
+ ,bool NeedMidpointRates
+ ,round_to<double> const& round_interest_rate
+ ,round_to<double> const& round_minutiae
+ ,std::vector<double> const& VectorExtraCompLoad
+ ,std::vector<double> const& VectorExtraAssetComp
+ ,std::vector<currency> const& VectorExtraPolFee
+ ,std::vector<double> const& TabularGuarSpecAmtLoad
+ ,std::vector<double> const& TabularCurrSpecAmtLoad
)
:length_ {length}
,AmortizePremLoad_ {AmortizePremLoad}
@@ -122,23 +131,23 @@ struct load_details
,TabularCurrSpecAmtLoad_ {TabularCurrSpecAmtLoad}
{}
- int length_;
- bool AmortizePremLoad_;
- double premium_tax_load_;
- double maximum_premium_tax_load_rate_;
- double minimum_premium_tax_load_rate_;
- double premium_tax_rate_;
- double premium_tax_amortization_rate_;
- int premium_tax_amortization_period_;
- oenum_asset_charge_type asset_charge_type_;
- bool NeedMidpointRates_;
- round_to<double> const& round_interest_rate_;
- round_to<double> const& round_minutiae_;
- std::vector<double> const& VectorExtraCompLoad_;
- std::vector<double> const& VectorExtraAssetComp_;
- std::vector<double> const& VectorExtraPolFee_;
- std::vector<double> const TabularGuarSpecAmtLoad_;
- std::vector<double> const TabularCurrSpecAmtLoad_;
+ int length_;
+ bool AmortizePremLoad_;
+ double premium_tax_load_;
+ double maximum_premium_tax_load_rate_;
+ double minimum_premium_tax_load_rate_;
+ double premium_tax_rate_;
+ double premium_tax_amortization_rate_;
+ int premium_tax_amortization_period_;
+ oenum_asset_charge_type asset_charge_type_;
+ bool NeedMidpointRates_;
+ round_to<double> const& round_interest_rate_;
+ round_to<double> const& round_minutiae_;
+ std::vector<double> const& VectorExtraCompLoad_;
+ std::vector<double> const& VectorExtraAssetComp_;
+ std::vector<currency> const VectorExtraPolFee_;
+ std::vector<double> const TabularGuarSpecAmtLoad_;
+ std::vector<double> const TabularCurrSpecAmtLoad_;
};
#endif // loads_impl_hpp
diff --git a/outlay.cpp b/outlay.cpp
index 5aaa8fe..540cc8d 100644
--- a/outlay.cpp
+++ b/outlay.cpp
@@ -49,41 +49,41 @@ modal_outlay::modal_outlay
{
}
-void modal_outlay::set_external_1035_amount(double z)
+void modal_outlay::set_external_1035_amount(currency z)
{
external_1035_amount_ = round_gross_premium_(z);
}
-void modal_outlay::set_internal_1035_amount(double z)
+void modal_outlay::set_internal_1035_amount(currency z)
{
internal_1035_amount_ = round_gross_premium_(z);
}
-void modal_outlay::set_ee_modal_premiums(double z, int from_year, int to_year)
+void modal_outlay::set_ee_modal_premiums(currency z, int from_year, int
to_year)
{
z = round_gross_premium_(z);
std::fill_n(ee_modal_premiums_.begin() + from_year, to_year - from_year,
z);
}
-void modal_outlay::set_er_modal_premiums(double z, int from_year, int to_year)
+void modal_outlay::set_er_modal_premiums(currency z, int from_year, int
to_year)
{
z = round_gross_premium_(z);
std::fill_n(er_modal_premiums_.begin() + from_year, to_year - from_year,
z);
}
-void modal_outlay::set_er_modal_premiums(std::vector<double> const& z)
+void modal_outlay::set_er_modal_premiums(std::vector<currency> const& z)
{
LMI_ASSERT(z.size() == er_modal_premiums_.size());
er_modal_premiums_ = round_gross_premium_(z);
}
-void modal_outlay::set_withdrawals(double z, int from_year, int to_year)
+void modal_outlay::set_withdrawals(currency z, int from_year, int to_year)
{
z = round_withdrawal_(z);
std::fill_n(withdrawals_.begin() + from_year, to_year - from_year, z);
}
-void modal_outlay::set_new_cash_loans(double z, int from_year, int to_year)
+void modal_outlay::set_new_cash_loans(currency z, int from_year, int to_year)
{
z = round_loan_(z);
std::fill_n(new_cash_loans_.begin() + from_year, to_year - from_year, z);
diff --git a/outlay.hpp b/outlay.hpp
index 2828c7d..04031cb 100644
--- a/outlay.hpp
+++ b/outlay.hpp
@@ -24,6 +24,7 @@
#include "config.hpp"
+#include "currency.hpp"
#include "mc_enum_type_enums.hpp"
#include "round_to.hpp"
@@ -44,61 +45,61 @@ class modal_outlay final
);
~modal_outlay() = default;
- double dumpin () const;
- double external_1035_amount () const;
- double internal_1035_amount () const;
- std::vector<double> const& ee_modal_premiums () const;
+ currency dumpin () const;
+ currency external_1035_amount () const;
+ currency internal_1035_amount () const;
+ std::vector<currency> const& ee_modal_premiums () const;
std::vector<mcenum_mode> const& ee_premium_modes () const;
- std::vector<double> const& er_modal_premiums () const;
+ std::vector<currency> const& er_modal_premiums () const;
std::vector<mcenum_mode> const& er_premium_modes () const;
- std::vector<double> const& withdrawals () const;
- std::vector<double> const& new_cash_loans () const;
+ std::vector<currency> const& withdrawals () const;
+ std::vector<currency> const& new_cash_loans () const;
private:
modal_outlay(modal_outlay const&) = delete;
modal_outlay& operator=(modal_outlay const&) = delete;
// Not yet used, but needed for MEC avoidance.
- void set_external_1035_amount(double z);
- void set_internal_1035_amount(double z);
+ void set_external_1035_amount(currency z);
+ void set_internal_1035_amount(currency z);
- void set_ee_modal_premiums(double z, int from_year, int to_year);
- void set_er_modal_premiums(double z, int from_year, int to_year);
- void set_er_modal_premiums(std::vector<double> const&);
- void set_withdrawals (double z, int from_year, int to_year);
- void set_new_cash_loans (double z, int from_year, int to_year);
+ void set_ee_modal_premiums(currency z, int from_year, int to_year);
+ void set_er_modal_premiums(currency z, int from_year, int to_year);
+ void set_er_modal_premiums(std::vector<currency> const&);
+ void set_withdrawals (currency z, int from_year, int to_year);
+ void set_new_cash_loans (currency z, int from_year, int to_year);
round_to<double> round_gross_premium_;
round_to<double> round_withdrawal_;
round_to<double> round_loan_;
- double dumpin_;
- double external_1035_amount_;
- double internal_1035_amount_;
- std::vector<double> ee_modal_premiums_;
+ currency dumpin_;
+ currency external_1035_amount_;
+ currency internal_1035_amount_;
+ std::vector<currency> ee_modal_premiums_;
std::vector<mcenum_mode> ee_premium_modes_;
- std::vector<double> er_modal_premiums_;
+ std::vector<currency> er_modal_premiums_;
std::vector<mcenum_mode> er_premium_modes_;
- std::vector<double> withdrawals_;
- std::vector<double> new_cash_loans_;
+ std::vector<currency> withdrawals_;
+ std::vector<currency> new_cash_loans_;
};
-inline double modal_outlay::dumpin() const
+inline currency modal_outlay::dumpin() const
{
return dumpin_;
}
-inline double modal_outlay::external_1035_amount() const
+inline currency modal_outlay::external_1035_amount() const
{
return external_1035_amount_;
}
-inline double modal_outlay::internal_1035_amount() const
+inline currency modal_outlay::internal_1035_amount() const
{
return internal_1035_amount_;
}
-inline std::vector<double> const& modal_outlay::ee_modal_premiums() const
+inline std::vector<currency> const& modal_outlay::ee_modal_premiums() const
{
return ee_modal_premiums_;
}
@@ -108,7 +109,7 @@ inline std::vector<mcenum_mode> const&
modal_outlay::ee_premium_modes() const
return ee_premium_modes_;
}
-inline std::vector<double> const& modal_outlay::er_modal_premiums() const
+inline std::vector<currency> const& modal_outlay::er_modal_premiums() const
{
return er_modal_premiums_;
}
@@ -118,12 +119,12 @@ inline std::vector<mcenum_mode> const&
modal_outlay::er_premium_modes() const
return er_premium_modes_;
}
-inline std::vector<double> const& modal_outlay::withdrawals() const
+inline std::vector<currency> const& modal_outlay::withdrawals() const
{
return withdrawals_;
}
-inline std::vector<double> const& modal_outlay::new_cash_loans() const
+inline std::vector<currency> const& modal_outlay::new_cash_loans() const
{
return new_cash_loans_;
}
diff --git a/solve.cpp b/solve.cpp
index fe89fc2..d65892d 100644
--- a/solve.cpp
+++ b/solve.cpp
@@ -61,7 +61,7 @@ namespace
//============================================================================
// This function isn't static and isn't in an unnamed namespace because
// that would make it difficult to grant it friendship.
-double SolveTest()
+currency SolveTest()
{
// Separate-account basis hardcoded because separate account not supported.
mcenum_run_basis temp;
@@ -180,9 +180,9 @@ inline static double SolveWD(double CandidateValue)
//============================================================================
void AccountValue::SolveSetPmts
- (double a_Pmt
- ,int ThatSolveBegYear
- ,int ThatSolveEndYear
+ (currency a_Pmt
+ ,int ThatSolveBegYear
+ ,int ThatSolveEndYear
)
{
Outlay_->set_ee_modal_premiums(a_Pmt, ThatSolveBegYear, ThatSolveEndYear);
@@ -190,9 +190,9 @@ void AccountValue::SolveSetPmts
//============================================================================
void AccountValue::SolveSetSpecAmt
- (double a_Bft
- ,int ThatSolveBegYear
- ,int ThatSolveEndYear
+ (currency a_Bft
+ ,int ThatSolveBegYear
+ ,int ThatSolveEndYear
)
{
DeathBfts_->set_specamt(a_Bft, ThatSolveBegYear, ThatSolveEndYear);
@@ -200,9 +200,9 @@ void AccountValue::SolveSetSpecAmt
//============================================================================
void AccountValue::SolveSetLoans
- (double a_Loan
- ,int ThatSolveBegYear
- ,int ThatSolveEndYear
+ (currency a_Loan
+ ,int ThatSolveBegYear
+ ,int ThatSolveEndYear
)
{
Outlay_->set_new_cash_loans(a_Loan, ThatSolveBegYear, ThatSolveEndYear);
@@ -210,9 +210,9 @@ void AccountValue::SolveSetLoans
//============================================================================
void AccountValue::SolveSetWDs
- (double a_WD
- ,int ThatSolveBegYear
- ,int ThatSolveEndYear
+ (currency a_WD
+ ,int ThatSolveBegYear
+ ,int ThatSolveEndYear
)
{
Outlay_->set_withdrawals(a_WD, ThatSolveBegYear, ThatSolveEndYear);
@@ -220,16 +220,16 @@ void AccountValue::SolveSetWDs
//============================================================================
void AccountValue::SolveSetLoanThenWD
- (double // Amt
- ,int // ThatSolveBegYear
- ,int // ThatSolveEndYear
+ (currency // Amt
+ ,int // ThatSolveBegYear
+ ,int // ThatSolveEndYear
)
{
// IHS !! Implemented in lmi.
}
//============================================================================
-double AccountValue::Solve()
+currency AccountValue::Solve()
{
That = this;
ThatSolveTargetValue = yare_input_.SolveTargetValue;
- [lmi-commits] [lmi] valyuta/005 ffa2ce4 09/17: Redesign unit test, (continued)
- [lmi-commits] [lmi] valyuta/005 ffa2ce4 09/17: Redesign unit test, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 90d7483 10/17: Improve currency class, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 3d44f42 13/17: Save a sorted list of regressions, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 c8864d3 04/17: Add commented-out relops, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 f3219f8 12/17: Use CURRENCY_UNIT_IS_CENTS appropriately, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 aad51dd 07/17: Inline more, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 b852a68 05/17: Add features, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 d69f05c 06/17: Ratify some regression-testing differences, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 2aae91a 14/17: Improve incrementally, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 0735250 15/17: Improve incrementally, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 dfdbf3c 16/17: Use currency type for class members as appropriate,
Greg Chicares <=
- [lmi-commits] [lmi] valyuta/005 221c094 08/17: Prefer constexpr, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 4401725 17/17: Merge branch 'master' into valyuta/005, Greg Chicares, 2021/01/16
- [lmi-commits] [lmi] valyuta/005 e3f3eff 11/17: Revert "Ratify some regression-testing differences", Greg Chicares, 2021/01/16