[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] valyuta/005 e40980b 05/10: Optionally detect noninte
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] valyuta/005 e40980b 05/10: Optionally detect nonintegral cents at run time |
Date: |
Thu, 21 Jan 2021 17:48:15 -0500 (EST) |
branch: valyuta/005
commit e40980b3020f3912a91e3cfa97a4355e44b78dce
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Optionally detect nonintegral cents at run time
This test is costly and should normally be suppressed. Precondition
validation isn't suppressed elsewhere in lmi; this case is different
because the deliberately cumbersome explicit ctor is almost never used
except with an argument that has just been rounded to an exact integral
value. This is just a transitional aid until "almost never" becomes
"never".
The 'Speed*' files show the cost for solve-heavy tests to be about six
or seven percent for x86_64, and sixteen or seventeen percent for i686.
---
Speed_gcc_i686-w64-mingw32 | 12 ++++++------
Speed_gcc_x86_64-pc-linux-gnu | 12 ++++++------
Speed_gcc_x86_64-w64-mingw32 | 12 ++++++------
currency.hpp | 18 +++++++++++++++---
currency_test.cpp | 17 ++++++++++++-----
5 files changed, 45 insertions(+), 26 deletions(-)
diff --git a/Speed_gcc_i686-w64-mingw32 b/Speed_gcc_i686-w64-mingw32
index 1c75cd7..92be5a8 100644
--- a/Speed_gcc_i686-w64-mingw32
+++ b/Speed_gcc_i686-w64-mingw32
@@ -1,7 +1,7 @@
Test speed:
- naic, no solve : 5.497e-02 s mean; 52960 us least of 19 runs
- naic, specamt solve : 9.961e-02 s mean; 98756 us least of 11 runs
- naic, ee prem solve : 9.104e-02 s mean; 89993 us least of 11 runs
- finra, no solve : 1.662e-02 s mean; 16412 us least of 61 runs
- finra, specamt solve: 5.865e-02 s mean; 58050 us least of 18 runs
- finra, ee prem solve: 5.406e-02 s mean; 53527 us least of 19 runs
+ naic, no solve : 6.283e-02 s mean; 62216 us least of 16 runs
+ naic, specamt solve : 1.158e-01 s mean; 115250 us least of 9 runs
+ naic, ee prem solve : 1.053e-01 s mean; 104619 us least of 10 runs
+ finra, no solve : 1.770e-02 s mean; 17407 us least of 57 runs
+ finra, specamt solve: 6.567e-02 s mean; 65102 us least of 16 runs
+ finra, ee prem solve: 6.045e-02 s mean; 59822 us least of 17 runs
diff --git a/Speed_gcc_x86_64-pc-linux-gnu b/Speed_gcc_x86_64-pc-linux-gnu
index 66dd9a3..5bb8ad4 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 : 2.124e-02 s mean; 20219 us least of 48 runs
- naic, specamt solve : 3.703e-02 s mean; 36600 us least of 28 runs
- naic, ee prem solve : 3.373e-02 s mean; 33333 us least of 30 runs
- finra, no solve : 5.945e-03 s mean; 5678 us least of 100 runs
- finra, specamt solve: 2.094e-02 s mean; 20673 us least of 48 runs
- finra, ee prem solve: 1.943e-02 s mean; 19163 us least of 52 runs
+ naic, no solve : 2.228e-02 s mean; 21562 us least of 45 runs
+ naic, specamt solve : 3.938e-02 s mean; 38908 us least of 26 runs
+ naic, ee prem solve : 3.572e-02 s mean; 35374 us least of 28 runs
+ finra, no solve : 6.131e-03 s mean; 5817 us least of 100 runs
+ finra, specamt solve: 2.200e-02 s mean; 21553 us least of 46 runs
+ finra, ee prem solve: 2.026e-02 s mean; 19766 us least of 50 runs
diff --git a/Speed_gcc_x86_64-w64-mingw32 b/Speed_gcc_x86_64-w64-mingw32
index c270e75..f4554d9 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.750e-02 s mean; 27221 us least of 37 runs
- naic, specamt solve : 4.707e-02 s mean; 46764 us least of 22 runs
- naic, ee prem solve : 4.326e-02 s mean; 42926 us least of 24 runs
- finra, no solve : 1.043e-02 s mean; 10253 us least of 96 runs
- finra, specamt solve: 2.825e-02 s mean; 27989 us least of 36 runs
- finra, ee prem solve: 2.625e-02 s mean; 26057 us least of 39 runs
+ naic, no solve : 2.955e-02 s mean; 29217 us least of 34 runs
+ naic, specamt solve : 5.044e-02 s mean; 49875 us least of 20 runs
+ naic, ee prem solve : 4.615e-02 s mean; 45675 us least of 22 runs
+ finra, no solve : 1.073e-02 s mean; 10507 us least of 94 runs
+ finra, specamt solve: 2.965e-02 s mean; 29297 us least of 34 runs
+ finra, ee prem solve: 2.767e-02 s mean; 27244 us least of 37 runs
diff --git a/currency.hpp b/currency.hpp
index 45e11d7..b94c9d2 100644
--- a/currency.hpp
+++ b/currency.hpp
@@ -24,7 +24,9 @@
#include "config.hpp"
+#include <cmath> // rint()
#include <ostream>
+#include <stdexcept> // runtime_error
#include <vector>
// Macros USE_CURRENCY_CLASS and CURRENCY_UNIT_IS_CENTS are used
@@ -35,6 +37,7 @@
#if !defined USE_CURRENCY_CLASS
# undef CURRENCY_UNIT_IS_CENTS // Requires currency class.
+# undef DETECT_NONINTEGRAL_CENTS // Meaningful only with currency class.
using currency = double;
@@ -50,6 +53,7 @@ inline std::vector<double> dblize(std::vector<currency>
const& z)
#else // defined USE_CURRENCY_CLASS
# define CURRENCY_UNIT_IS_CENTS
+# define DETECT_NONINTEGRAL_CENTS
class raw_cents {}; // Tag class.
@@ -75,7 +79,17 @@ class currency
currency& operator=(currency const&) = default;
~currency() = default;
- explicit currency(data_type z, raw_cents) : m_ {z} {assert_integral(z);}
+ explicit currency(data_type z, raw_cents) : m_ {z}
+ {
+# if defined DETECT_NONINTEGRAL_CENTS
+ // CURRENCY !! Consider removing this test altogether, and
+ // making the explicit ctor private so that only friend
+ // template class round_to can use it (with arguments that
+ // are certainly exact integers because they have just been
+ // rounded).
+ if(z != std::rint(z)) throw std::runtime_error("Nonintegral cents.");
+# endif // defined DETECT_NONINTEGRAL_CENTS
+ }
currency& operator+=(currency z) {m_ += z.m_; return *this;}
currency& operator-=(currency z) {m_ -= z.m_; return *this;}
@@ -88,8 +102,6 @@ class currency
double d() const {return m_ / cents_per_dollar;}
private:
- // CURRENCY !! Actually implement this.
- void assert_integral(data_type) {}
data_type m_ = {};
};
diff --git a/currency_test.cpp b/currency_test.cpp
index 5393d6d..897534b 100644
--- a/currency_test.cpp
+++ b/currency_test.cpp
@@ -99,6 +99,16 @@ void currency_test::test_explicit_ctor()
{
currency const a1(325, raw_cents{});
BOOST_TEST_EQUAL( 325, a1.m_);
+#if defined DETECT_NONINTEGRAL_CENTS
+ // 1/64 is an exact binary constant, so 100/64 cents could be
+ // converted to 1/64 dollars and back without loss of precision;
+ // but that's outside the intended scope of the currency class.
+ BOOST_TEST_THROW
+ ((currency {1.5625, raw_cents {}})
+ ,std::runtime_error
+ ,"Nonintegral cents."
+ );
+#endif // defined DETECT_NONINTEGRAL_CENTS
}
void currency_test::test_negation()
@@ -179,13 +189,10 @@ void currency_test::test_relops()
void currency_test::test_stream_inserter()
{
- // 1/64 is an exact binary constant, with so few digits that it
- // must print with full precision by default. However, it's not
- // integral, and therefore probably should be forbidden.
- currency const a3 {0.015625, raw_cents {}};
+ currency const a3 {123456, raw_cents {}};
std::ostringstream oss;
oss << a3;
- BOOST_TEST_EQUAL("0.00015625", oss.str());
+ BOOST_TEST_EQUAL("1234.56", oss.str());
}
void currency_test::test_dollars()
- [lmi-commits] [lmi] valyuta/005 updated (133d646 -> 9e42155), Greg Chicares, 2021/01/21
- [lmi-commits] [lmi] valyuta/005 d763c34 04/10: Clean up, Greg Chicares, 2021/01/21
- [lmi-commits] [lmi] valyuta/005 2712277 02/10: Default class currency's special member functions, Greg Chicares, 2021/01/21
- [lmi-commits] [lmi] valyuta/005 86cba7f 09/10: Temporarily don't use currency class, Greg Chicares, 2021/01/21
- [lmi-commits] [lmi] valyuta/005 7f6a453 01/10: Revert "Partially revert the last commit", Greg Chicares, 2021/01/21
- [lmi-commits] [lmi] valyuta/005 c0a93cf 03/10: Reorder currency unit tests, Greg Chicares, 2021/01/21
- [lmi-commits] [lmi] valyuta/005 e40980b 05/10: Optionally detect nonintegral cents at run time,
Greg Chicares <=
- [lmi-commits] [lmi] valyuta/005 61396fd 06/10: Expunge the unclean macro just added, Greg Chicares, 2021/01/21
- [lmi-commits] [lmi] valyuta/005 4b0bf87 07/10: Detect nonintegral cents along every path, Greg Chicares, 2021/01/21
- [lmi-commits] [lmi] valyuta/005 6767160 08/10: Temporarily don't use cents, Greg Chicares, 2021/01/21
- [lmi-commits] [lmi] valyuta/005 9e42155 10/10: Undo temporary changes: use currency class with cents, Greg Chicares, 2021/01/21