[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 67af2e9b 5/9: Improve a debatable workaround
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 67af2e9b 5/9: Improve a debatable workaround |
Date: |
Fri, 6 May 2022 19:37:36 -0400 (EDT) |
branch: master
commit 67af2e9bdba0c4e2edbb0f0e8d9a60a00610ce08
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Improve a debatable workaround
It seems unlikely that the situation described in commit f97235aed48a52
could be a problem for the inverse operation, i.e., calculating premium
according to a corridor strategy. For a 4.9000000000000003552713679
corridor factor that is notionally 490/100 but has representation error:
specamt = roundup ($100000 * factor) // 490001: wrong
because 0.00000000003552713679 rounds up to 1; but
premium = rounddown($100000 / factor) // 20408.1632653...
has no such problem. Thus, this function's body might be written as:
return round_max_premium().c((a_specamt / rate) / a_mode);
Instead, however, committed an implementation that closely parallels
BasicValues::GetModalSpecAmtCorridor(), lest a corridor factor like
250% be read from file as, say, 2.5 * (1 + epsilon), however unlikely
that may seem.
Made no such change in AccountValue::TxAscertainDesiredPayment(),
where a similar calculation is used for an error message. In that case
(an exotic idiosyncrasy of a particular product), the premium is
multiplied by 'MinSinglePremiumMult', whose value needn't be rational,
even notionally.
---
ihs_basicval.cpp | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/ihs_basicval.cpp b/ihs_basicval.cpp
index f730c631..bbb113eb 100644
--- a/ihs_basicval.cpp
+++ b/ihs_basicval.cpp
@@ -999,7 +999,13 @@ currency BasicValues::GetModalPremCorridor
) const
{
double const rate = GetCorridorFactor()[0];
- return round_max_premium().c(ldbl_eps_plus_one_times((a_specamt / rate) /
a_mode));
+ int const k = round_corridor_factor().decimals();
+ double const s = nonstd::power(10, k);
+ // Do not save and restore prior rounding direction because
+ // lmi generally expects rounding to nearest everywhere.
+ std::fesetround(FE_TONEAREST);
+ double const z = std::nearbyint(s * rate);
+ return round_max_premium().c((a_specamt / z) * s / a_mode);
}
//============================================================================
- [lmi-commits] [lmi] master updated (13799952 -> 9e5a09bf), Greg Chicares, 2022/05/06
- [lmi-commits] [lmi] master be841c05 3/9: Refactor for clarity, Greg Chicares, 2022/05/06
- [lmi-commits] [lmi] master a24d665c 4/9: Include only appropriate headers, and say why they're included, Greg Chicares, 2022/05/06
- [lmi-commits] [lmi] master 46534540 2/9: Refactor for uniformity, Greg Chicares, 2022/05/06
- [lmi-commits] [lmi] master 9e5a09bf 9/9: Record speed measurements, Greg Chicares, 2022/05/06
- [lmi-commits] [lmi] master 78657d01 6/9: Improve physical structure, Greg Chicares, 2022/05/06
- [lmi-commits] [lmi] master 4b8bf312 1/9: Expunge workarounds for nonexistent problems, Greg Chicares, 2022/05/06
- [lmi-commits] [lmi] master 67af2e9b 5/9: Improve a debatable workaround,
Greg Chicares <=
- [lmi-commits] [lmi] master 205497ae 8/9: Reimplement max_modal_premium(), Greg Chicares, 2022/05/06
- [lmi-commits] [lmi] master 1de83b9d 7/9: Refactor, Greg Chicares, 2022/05/06