[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 62c89fd 7/7: Use currency type for some poten
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 62c89fd 7/7: Use currency type for some potentially-infinite limits |
Date: |
Thu, 4 Feb 2021 16:44:33 -0500 (EST) |
branch: master
commit 62c89fd060e343c07349cf5bb76179e1f93174d4
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Use currency type for some potentially-infinite limits
These limits are currency amounts, and currency types have recently been
shown to work well with infinities.
---
basic_values.hpp | 10 +++++-----
ihs_avmly.cpp | 11 ++++++-----
ihs_basicval.cpp | 41 ++++++++++++++++++++++++-----------------
3 files changed, 35 insertions(+), 27 deletions(-)
diff --git a/basic_values.hpp b/basic_values.hpp
index 5d71cb2..d71db68 100644
--- a/basic_values.hpp
+++ b/basic_values.hpp
@@ -338,8 +338,8 @@ class LMI_SO BasicValues
oenum_modal_prem_type TgtPremType;
bool TgtPremFixedAtIssue;
currency TgtPremMonthlyPolFee;
- double CurrCoiTable0Limit; // CURRENCY !! may be
infinity
- double CurrCoiTable1Limit; // CURRENCY !! may be
infinity
+ currency CurrCoiTable0Limit;
+ currency CurrCoiTable1Limit;
e_actuarial_table_method CoiInforceReentry;
mcenum_anticipated_deduction MaxWDDed_;
double MaxWdGenAcctValMult;
@@ -357,9 +357,9 @@ class LMI_SO BasicValues
bool SurrChgOnDecr;
std::vector<double> FreeWDProportion;
- double AdbLimit; // CURRENCY !! may be infinity
- double WpLimit; // CURRENCY !! may be infinity
- double SpecAmtLoadLimit; // CURRENCY !! may be infinity
+ currency AdbLimit;
+ currency WpLimit;
+ currency SpecAmtLoadLimit;
currency MinWD;
currency WDFee;
double WDFeeRate;
diff --git a/ihs_avmly.cpp b/ihs_avmly.cpp
index 0052a2d..1d1de7a 100644
--- a/ihs_avmly.cpp
+++ b/ihs_avmly.cpp
@@ -1566,7 +1566,9 @@ void AccountValue::TxSetBOMAV()
{
LMI_ASSERT(C0 == term_specamt(0));
}
- LMI_ASSERT(yare_input_.InforceSpecAmtLoadBase <= SpecAmtLoadLimit);
+ // CURRENCY !! Should yare_input convert currency inputs to
+ // type currency, which is more yare than double?
+ LMI_ASSERT(yare_input_.InforceSpecAmtLoadBase <=
dblize(SpecAmtLoadLimit));
SpecAmtLoadBase =
(0 == Year && 0 == Month)
? std::max
@@ -1575,8 +1577,7 @@ void AccountValue::TxSetBOMAV()
)
: round_specamt().c(yare_input_.InforceSpecAmtLoadBase)
;
- // CURRENCY !! support infinities?
- SpecAmtLoadBase = round_specamt().c(std::min(dblize(SpecAmtLoadBase),
SpecAmtLoadLimit));
+ SpecAmtLoadBase = std::min(SpecAmtLoadBase, SpecAmtLoadLimit);
}
// These assignments must happen every month.
@@ -1825,7 +1826,7 @@ void AccountValue::TxSetRiderDed()
if(yare_input_.AccidentalDeathBenefit)
{
AdbCharge = round_rider_charges().c
- (YearsAdbRate * std::min(dblize(ActualSpecAmt), AdbLimit)
+ (YearsAdbRate * std::min(ActualSpecAmt, AdbLimit)
);
}
@@ -1868,7 +1869,7 @@ void AccountValue::TxSetRiderDed()
case oe_waiver_times_specamt:
{
WpCharge = round_rider_charges().c
- (YearsWpRate * std::min(dblize(ActualSpecAmt), WpLimit)
+ (YearsWpRate * std::min(ActualSpecAmt, WpLimit)
);
DcvWpCharge = dblize(WpCharge);
}
diff --git a/ihs_basicval.cpp b/ihs_basicval.cpp
index 0d40081..8f3835a 100644
--- a/ihs_basicval.cpp
+++ b/ihs_basicval.cpp
@@ -473,7 +473,7 @@ void BasicValues::Init7702()
local_mly_charge_add = GetAdbRates();
}
- double local_adb_limit = database().query<bool>(DB_AdbIsQAB) ? AdbLimit :
0.0;
+ double local_adb_limit = database().query<bool>(DB_AdbIsQAB) ?
dblize(AdbLimit) : 0.0;
// BasicValues::InitialTargetPremium is used only here. For
// standalone GPT calculations, it's an input field. For
@@ -499,7 +499,7 @@ void BasicValues::Init7702()
,dblize(Loads_->annual_policy_fee (mce_gen_curr))
,dblize(Loads_->monthly_policy_fee (mce_gen_curr))
,Loads_->specified_amount_load (mce_gen_curr)
- ,SpecAmtLoadLimit
+ ,dblize(SpecAmtLoadLimit)
,local_mly_charge_add
,local_adb_limit
/// TAXATION !! No contemporary authority seems to believe that a
@@ -587,8 +587,11 @@ void BasicValues::SetPermanentInvariants()
LMI_ASSERT(C0 == TgtPremMonthlyPolFee || oe_modal_table == TgtPremType);
database().query_into(DB_CurrCoiTable0Limit , CurrCoiTable0Limit);
database().query_into(DB_CurrCoiTable1Limit , CurrCoiTable1Limit);
- LMI_ASSERT(0.0 <= CurrCoiTable0Limit);
+ LMI_ASSERT(C0 <= CurrCoiTable0Limit);
LMI_ASSERT(CurrCoiTable0Limit <= CurrCoiTable1Limit);
+ // Make sure database contents have no excess precision.
+ LMI_ASSERT(round_specamt().c(CurrCoiTable0Limit) == CurrCoiTable0Limit);
+ LMI_ASSERT(round_specamt().c(CurrCoiTable1Limit) == CurrCoiTable1Limit);
database().query_into(DB_CoiInforceReentry , CoiInforceReentry);
database().query_into(DB_MaxWdDed , MaxWDDed_);
database().query_into(DB_MaxWdGenAcctValMult , MaxWdGenAcctValMult);
@@ -602,6 +605,10 @@ void BasicValues::SetPermanentInvariants()
database().query_into(DB_AdbLimit , AdbLimit);
database().query_into(DB_WpLimit , WpLimit);
database().query_into(DB_SpecAmtLoadLimit , SpecAmtLoadLimit);
+ // Make sure database contents have no excess precision.
+ LMI_ASSERT(round_specamt().c(AdbLimit) == AdbLimit);
+ LMI_ASSERT(round_specamt().c(WpLimit) == WpLimit);
+ LMI_ASSERT(round_specamt().c(SpecAmtLoadLimit) == SpecAmtLoadLimit);
database().query_into(DB_MinWd , MinWD);
database().query_into(DB_WdFee , WDFee);
// Make sure database contents have no excess precision.
@@ -1146,11 +1153,7 @@ std::pair<double,double> BasicValues::approx_mly_ded
if(yare_input_.AccidentalDeathBenefit)
{
double const r = MortalityRates_->AdbRates()[year];
- // CURRENCY !! Here and elsewhere in this file, consider
- // letting currency objects assume infinite values--so that
- // 'AdbLimit' could be of currency type, and dblize() would
- // not be needed.
- mly_ded += r * std::min(dblize(specamt), AdbLimit);
+ mly_ded += r * std::min(specamt, AdbLimit);
}
if(yare_input_.SpouseRider)
@@ -1168,7 +1171,7 @@ std::pair<double,double> BasicValues::approx_mly_ded
if(true) // Written thus for parallelism and to keep 'r' local.
{
double const r = Loads_->specified_amount_load(mce_gen_curr)[year];
- mly_ded += r * std::min(dblize(specamt), SpecAmtLoadLimit);
+ mly_ded += r * std::min(specamt, SpecAmtLoadLimit);
}
mly_ded += dblize(Loads_->monthly_policy_fee(mce_gen_curr)[year]);
@@ -1182,7 +1185,7 @@ std::pair<double,double> BasicValues::approx_mly_ded
{
case oe_waiver_times_specamt:
{
- mly_ded += r * std::min(dblize(specamt), WpLimit);
+ mly_ded += r * std::min(specamt, WpLimit);
}
break;
case oe_waiver_times_deductions:
@@ -1240,7 +1243,7 @@ std::pair<double,double> BasicValues::approx_mly_ded_ex
if(yare_input_.AccidentalDeathBenefit)
{
double const r = MortalityRates_->AdbRates()[year];
- er_ded += r * std::min(dblize(specamt), AdbLimit);
+ er_ded += r * std::min(specamt, AdbLimit);
}
// Paid by ee.
@@ -1261,7 +1264,7 @@ std::pair<double,double> BasicValues::approx_mly_ded_ex
if(true) // Written thus for parallelism and to keep 'r' local.
{
double const r = Loads_->specified_amount_load(mce_gen_curr)[year];
- er_ded += r * std::min(dblize(specamt), SpecAmtLoadLimit);
+ er_ded += r * std::min(specamt, SpecAmtLoadLimit);
}
// Paid by er.
@@ -1275,7 +1278,7 @@ std::pair<double,double> BasicValues::approx_mly_ded_ex
case oe_waiver_times_specamt:
{
// Paid by er. (In this case, WP excludes term.)
- er_ded += r * std::min(dblize(specamt), WpLimit);
+ er_ded += r * std::min(specamt, WpLimit);
}
break;
case oe_waiver_times_deductions:
@@ -1569,11 +1572,11 @@ std::vector<double> const&
BasicValues::GetBandedCoiRates
{
if(UseUnusualCOIBanding && mce_gen_guar != rate_basis)
{
- if(CurrCoiTable0Limit <= dblize(a_specamt) && dblize(a_specamt) <
CurrCoiTable1Limit)
+ if(CurrCoiTable0Limit <= a_specamt && a_specamt < CurrCoiTable1Limit)
{
return MortalityRates_->MonthlyCoiRatesBand1(rate_basis);
}
- else if(CurrCoiTable1Limit <= dblize(a_specamt))
+ else if(CurrCoiTable1Limit <= a_specamt)
{
return MortalityRates_->MonthlyCoiRatesBand2(rate_basis);
}
@@ -1956,10 +1959,12 @@ std::vector<double> BasicValues::GetCurrCOIRates0()
const
std::vector<double> BasicValues::GetCurrCOIRates1() const
{
+ static constexpr double dbl_inf = std::numeric_limits<double>::infinity();
+ static const currency inf = from_cents(dbl_inf);
return GetTable
(product().datum("CurrCOIFilename")
,DB_CurrCoiTable1
- ,!isinf(CurrCoiTable0Limit)
+ ,CurrCoiTable0Limit < inf
,CanBlend
,CanBlend
);
@@ -1967,10 +1972,12 @@ std::vector<double> BasicValues::GetCurrCOIRates1()
const
std::vector<double> BasicValues::GetCurrCOIRates2() const
{
+ static constexpr double dbl_inf = std::numeric_limits<double>::infinity();
+ static const currency inf = from_cents(dbl_inf);
return GetTable
(product().datum("CurrCOIFilename")
,DB_CurrCoiTable2
- ,!isinf(CurrCoiTable1Limit)
+ ,CurrCoiTable1Limit < inf
,CanBlend
,CanBlend
);
- [lmi-commits] [lmi] master updated (53a8634 -> 62c89fd), Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master 8738f07 5/7: Improve concinnity of database descriptions, Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master a8e24b0 6/7: Rectify a strange test for infinity, Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master 62c89fd 7/7: Use currency type for some potentially-infinite limits,
Greg Chicares <=
- [lmi-commits] [lmi] master 2cf0e24 1/7: Overload query_into() for currency, Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master 0d94134 2/7: Note a possible improvement, Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master dcc33f1 3/7: Replace a free function with a better general implementation, Greg Chicares, 2021/02/04
- [lmi-commits] [lmi] master 48aa040 4/7: Use recently added query_into() overload for currency, Greg Chicares, 2021/02/04