[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] odd/eraseme 29cc65c 2/4: Expunge USE_CURRENCY_CLASS
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] odd/eraseme 29cc65c 2/4: Expunge USE_CURRENCY_CLASS |
Date: |
Fri, 5 Mar 2021 14:08:07 -0500 (EST) |
branch: odd/eraseme
commit 29cc65c90c8850d00f031e7f52fe1b89460358c4
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Expunge USE_CURRENCY_CLASS
Removed the 'using currency = double;' option.
---
account_value.hpp | 2 --
currency.hpp | 23 -----------------------
currency_test.cpp | 5 -----
ihs_acctval.cpp | 6 +-----
ihs_avdebug.cpp | 2 --
ihs_avmly.cpp | 52 ++--------------------------------------------------
round_to.hpp | 36 ++++++++++++++++++++++++------------
round_to_test.cpp | 4 ----
8 files changed, 27 insertions(+), 103 deletions(-)
diff --git a/account_value.hpp b/account_value.hpp
index 06ebf12..44b712d 100644
--- a/account_value.hpp
+++ b/account_value.hpp
@@ -296,9 +296,7 @@ class LMI_SO AccountValue final
void SetMonthlyDetail(int enumerator, std::string const&);
void SetMonthlyDetail(int enumerator, double);
-#if defined USE_CURRENCY_CLASS
void SetMonthlyDetail(int enumerator, currency);
-#endif // defined USE_CURRENCY_CLASS
void DebugPrintInit();
void DebugEndBasis();
diff --git a/currency.hpp b/currency.hpp
index 1837b5d..ce04d75 100644
--- a/currency.hpp
+++ b/currency.hpp
@@ -29,27 +29,6 @@
#include <stdexcept> // runtime_error
#include <vector>
-// Macro USE_CURRENCY_CLASS is used
-// elsewhere. Eventually it'll be eliminated, along with
-// all code along paths where it isn't defined.
-
-#define USE_CURRENCY_CLASS
-
-#if !defined USE_CURRENCY_CLASS
-
-using currency = double;
-
-inline currency from_cents(double z) {return z / 100.0;}
-
-inline double dblize(currency z) {return z;}
-
-inline std::vector<double> dblize(std::vector<currency> const& z)
-{
- return z;
-}
-
-#else // defined USE_CURRENCY_CLASS
-
class raw_cents {}; // Tag class.
class currency
@@ -151,8 +130,6 @@ inline std::vector<double> dblize(std::vector<currency>
const& z)
return r;
}
-# endif // defined USE_CURRENCY_CLASS
-
/// Zero cents--akin to a user-defined literal.
///
/// UDLs seem less convenient because the obvious "0_c" is likely to
diff --git a/currency_test.cpp b/currency_test.cpp
index f20ffc8..b1f4970 100644
--- a/currency_test.cpp
+++ b/currency_test.cpp
@@ -64,7 +64,6 @@ class currency_test
void currency_test::test()
{
-#if defined USE_CURRENCY_CLASS
test_default_ctor();
test_copy_ctor();
test_explicit_ctor();
@@ -81,10 +80,8 @@ void currency_test::test()
test_round_currency();
test_infinite();
test_quodlibet();
-#endif // defined USE_CURRENCY_CLASS
}
-#if defined USE_CURRENCY_CLASS
void currency_test::test_default_ctor()
{
// default ctor
@@ -356,8 +353,6 @@ std::cout << big_int3 << '\n' << 1.0e102 << '\n' <<
big_int3 - 1.0e102 << std::e
);
#endif // 0
-#endif // defined USE_CURRENCY_CLASS
-
int test_main(int, char*[])
{
currency_test::test();
diff --git a/ihs_acctval.cpp b/ihs_acctval.cpp
index 3501d29..c6f1e97 100644
--- a/ihs_acctval.cpp
+++ b/ihs_acctval.cpp
@@ -633,12 +633,8 @@ void AccountValue::SetInitialValues()
HoneymoonActive = false;
// Identity element for std::max(), disregarding -INF and NaN.
- // CURRENCY !! support infinities?
-#if defined USE_CURRENCY_CLASS
+ // CURRENCY !! alternatively, use -INF
HoneymoonValue =
-from_cents(std::numeric_limits<currency::data_type>::max());
-#else // !defined USE_CURRENCY_CLASS
- HoneymoonValue = -std::numeric_limits<double>::max();
-#endif // !defined USE_CURRENCY_CLASS
if(mce_gen_curr == GenBasis_)
{
HoneymoonActive = yare_input_.HoneymoonEndorsement;
diff --git a/ihs_avdebug.cpp b/ihs_avdebug.cpp
index 866f78b..cdaac07 100644
--- a/ihs_avdebug.cpp
+++ b/ihs_avdebug.cpp
@@ -257,12 +257,10 @@ inline void AccountValue::SetMonthlyDetail(int
enumerator, double d)
}
//============================================================================
-#if defined USE_CURRENCY_CLASS
inline void AccountValue::SetMonthlyDetail(int enumerator, currency c)
{
DebugRecord[enumerator] = value_cast<std::string>(dblize(c));
}
-#endif // defined USE_CURRENCY_CLASS
//============================================================================
void AccountValue::SetDebugFilename(std::string const& s)
diff --git a/ihs_avmly.cpp b/ihs_avmly.cpp
index 2b58577..cd94fd6 100644
--- a/ihs_avmly.cpp
+++ b/ihs_avmly.cpp
@@ -428,11 +428,7 @@ void AccountValue::DecrementAVProportionally(currency
decrement)
{
decrement = round_minutiae().c(decrement); // CURRENCY !! already rounded?
-#if defined USE_CURRENCY_CLASS
if(decrement == AVGenAcct + AVSepAcct)
-#else // !defined USE_CURRENCY_CLASS
- if(materially_equal(decrement, AVGenAcct + AVSepAcct))
-#endif // !defined USE_CURRENCY_CLASS
{
AVGenAcct = C0;
AVSepAcct = C0;
@@ -495,11 +491,7 @@ void AccountValue::DecrementAVProgressively
,oenum_increment_account_preference preferred_account
)
{
-#if defined USE_CURRENCY_CLASS
if(decrement == AVGenAcct + AVSepAcct)
-#else // !defined USE_CURRENCY_CLASS
- if(materially_equal(decrement, AVGenAcct + AVSepAcct))
-#endif // !defined USE_CURRENCY_CLASS
{
AVGenAcct = C0;
AVSepAcct = C0;
@@ -1118,15 +1110,9 @@ void AccountValue::TxTestGPT()
// TAXATION !! This assumes the term rider can be treated as death benefit;
// use 'TermIsDbFor7702'.
bool adj_event =
-#if defined USE_CURRENCY_CLASS
( OldSA != ActualSpecAmt + TermSpecAmt
&& OldDB != DBReflectingCorr + TermDB
)
-#else // !defined USE_CURRENCY_CLASS
- ( !materially_equal(OldSA, ActualSpecAmt + TermSpecAmt)
- && !materially_equal(OldDB, DBReflectingCorr + TermDB)
- )
-#endif // !defined USE_CURRENCY_CLASS
|| old_dbopt != new_dbopt
;
if(adj_event)
@@ -1785,19 +1771,11 @@ void AccountValue::TxSetCoiCharge()
// than zero because the corridor factor can be as low as unity,
// but it's constrained to be nonnegative to prevent increasing
// the account value by deducting a negative mortality charge.
-#if defined USE_CURRENCY_CLASS
NAAR = round_naar().c
( DBReflectingCorr * DBDiscountRate[Year]
- dblize(std::max(C0, TotalAccountValue()))
);
NAAR = std::max(C0, NAAR);
-#else // !defined USE_CURRENCY_CLASS
- NAAR = material_difference
- (DBReflectingCorr * DBDiscountRate[Year]
- ,std::max(0.0, TotalAccountValue())
- );
- NAAR = std::max(0.0, round_naar()(NAAR));
-#endif // !defined USE_CURRENCY_CLASS
// TODO ?? This doesn't work. We need to reconsider the basic transactions.
// currency naar_forceout = std::max(0.0, NAAR - MaxNAAR);
@@ -1984,12 +1962,8 @@ void AccountValue::TxTestHoneymoonForExpiration()
if(HoneymoonValue <= C0 || HoneymoonValue < csv_ignoring_loan)
{
HoneymoonActive = false;
-#if defined USE_CURRENCY_CLASS
- // CURRENCY !! support infinities?
+ // CURRENCY !! alternatively, use -INF
HoneymoonValue =
-from_cents(std::numeric_limits<currency::data_type>::max());
-#else // !defined USE_CURRENCY_CLASS
- HoneymoonValue = -std::numeric_limits<double>::max();
-#endif // !defined USE_CURRENCY_CLASS
}
}
@@ -2154,25 +2128,8 @@ void AccountValue::TxCreditInt()
SepAcctIntCred = InterestCredited(AVSepAcct, YearsSepAcctIntRate);
currency gross = InterestCredited(AVSepAcct, YearsSepAcctGrossRate);
notional_sep_acct_charge = gross - SepAcctIntCred;
-#if defined USE_CURRENCY_CLASS
- // CURRENCY !! Further simplify the local logic after
- // expunging macro USE_CURRENCY_CLASS.
+ // CURRENCY !! Further simplify the local logic?
AVSepAcct = std::max(C0, AVSepAcct + SepAcctIntCred);
-#else // !defined USE_CURRENCY_CLASS
- // Guard against catastrophic cancellation. Testing the
- // absolute values of the addends for material equality is not
- // sufficient, because the interest increment has already been
- // rounded.
- double result = AVSepAcct + SepAcctIntCred;
- if(result < 0.0 && 0.0 <= AVSepAcct)
- {
- AVSepAcct = 0.0;
- }
- else
- {
- AVSepAcct = result;
- }
-#endif // !defined USE_CURRENCY_CLASS
}
else
{
@@ -2806,11 +2763,6 @@ void AccountValue::TxTestLapse()
( NoLapseMinAge <= Year + BasicValues::GetIssueAge()
&& NoLapseMinDur <= Year
|| CumPmts < CumNoLapsePrem
-#if defined USE_CURRENCY_CLASS
- // x<y --> x<>y for x,y integral
-#else // !defined USE_CURRENCY_CLASS
- && !materially_equal(CumPmts, CumNoLapsePrem)
-#endif // !defined USE_CURRENCY_CLASS
)
{
NoLapseActive = false;
diff --git a/round_to.hpp b/round_to.hpp
index 053f08d..d6f3718 100644
--- a/round_to.hpp
+++ b/round_to.hpp
@@ -270,10 +270,8 @@ class round_to
currency c(RealType) const;
std::vector<currency> c(std::vector<RealType> const&) const;
-#if defined USE_CURRENCY_CLASS
currency c(currency) const;
std::vector<currency> c(std::vector<currency> const&) const;
-#endif // defined USE_CURRENCY_CLASS
int decimals() const;
rounding_style style() const;
@@ -322,11 +320,7 @@ round_to<RealType>::round_to(int a_decimals,
rounding_style a_style)
,style_ {a_style}
,scale_fwd_ {detail::int_pow(max_prec_real(10.0), decimals_)}
,scale_back_ {max_prec_real(1.0) / scale_fwd_}
-#if defined USE_CURRENCY_CLASS
,decimals_cents_ {decimals_ - currency::cents_digits}
-#else // !defined USE_CURRENCY_CLASS
- ,decimals_cents_ {decimals_ - 0}
-#endif // ! defined USE_CURRENCY_CLASS
,scale_fwd_cents_ {detail::int_pow(max_prec_real(10.0), decimals_cents_)}
,scale_back_cents_ {max_prec_real(1.0) / scale_fwd_cents_}
,rounding_function_ {select_rounding_function(style_)}
@@ -390,6 +384,30 @@ inline std::vector<RealType> round_to<RealType>::operator()
return z;
}
+/// Round a double explicitly; return currency.
+///
+/// As long as the explicit rounding was to cents, or to a power of 10
+/// times cents, the result is an exact integer. For example, to round
+/// 1.234 to the nearest cent:
+/// 1.234 * 100.0 --> 123.400000000000005684342 // r * scale_fwd_ (=100.0)
+/// 123.400000000000005684342 --> 123.0 // rounding_function_()
+/// 123.0 --> 123.0 cents // * scale_back_cents_ (=1.0)
+/// or to the nearest dollar:
+/// 1.234 * 1.0 --> 1.229999999999999982236 // r * scale_fwd_ (=1.0)
+/// 1.229999999999999982236 --> 1.0 // rounding_function_()
+/// 1.0 --> 100.0 cents // * scale_back_cents_ (=100.0)
+/// It is rounding_function_(), not static_cast<>(), that transforms
+/// the floating-point argument to an exact integer value.
+///
+/// The reason this function exists is to intercept that integer value
+/// and multiply it by a nonnegative power of ten. If operator() were
+/// used instead and its result multiplied by 100, it would no longer
+/// be integral--in the first example above:
+/// 1.234 * 100.0 --> 123.400000000000005684342 // r * scale_fwd_ (=100.0)
+/// 123.400000000000005684342 --> 123.0 // rounding_function_()
+/// 123.0 --> 1.229999999999999982236 // * scale_back_ (=0.01)
+/// 1.229999999999999982236 * 100.0 --> nonintegral
+
template<typename RealType>
inline currency round_to<RealType>::c(RealType r) const
{
@@ -397,12 +415,8 @@ inline currency round_to<RealType>::c(RealType r) const
( rounding_function_(static_cast<RealType>(r * scale_fwd_))
* scale_back_cents_
);
-#if defined USE_CURRENCY_CLASS
// CURRENCY !! static_cast: possible range error
return currency(static_cast<currency::data_type>(z), raw_cents {});
-#else // !defined USE_CURRENCY_CLASS
- return currency(z);
-#endif // ! defined USE_CURRENCY_CLASS
}
template<typename RealType>
@@ -415,7 +429,6 @@ inline std::vector<currency> round_to<RealType>::c
return z;
}
-#if defined USE_CURRENCY_CLASS
// CURRENCY !! need unit tests
/// Round currency to a potentially different precision.
@@ -448,7 +461,6 @@ inline std::vector<currency> round_to<RealType>::c
for(auto const& i : v) {z.push_back(c(i));}
return z;
}
-#endif // defined USE_CURRENCY_CLASS
template<typename RealType>
int round_to<RealType>::decimals() const
diff --git a/round_to_test.cpp b/round_to_test.cpp
index 22266cd..ca45a1a 100644
--- a/round_to_test.cpp
+++ b/round_to_test.cpp
@@ -580,9 +580,7 @@ void round_to_test::test_fundamentals()
// Test rounding double to currency.
currency c = round0.c(1.61803398875);
LMI_TEST((1.62 - dblize(c)) < 1e-14);
-#if defined USE_CURRENCY_CLASS
LMI_TEST_EQUAL(162, c.cents());
-#endif // defined USE_CURRENCY_CLASS
// c *= 0.61803398875;
// LMI_TEST_EQUAL(1, c);
@@ -593,7 +591,6 @@ void round_to_test::test_fundamentals()
LMI_TEST((3.14 - v1[0]) < 1e-14);
LMI_TEST((2.72 - v1[1]) < 1e-14);
-#if defined USE_CURRENCY_CLASS
// Try to provoke division by zero in ctor-initializer.
//
// nonstd::power() negates a negative exponent, but negating
@@ -604,7 +601,6 @@ void round_to_test::test_fundamentals()
,std::domain_error
,"Invalid number of decimals."
);
-#endif // defined USE_CURRENCY_CLASS
}
void round_to_test::test()