lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 3d69769b 05/13: Demonstrate that a default co


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 3d69769b 05/13: Demonstrate that a default comparison tolerance works well
Date: Mon, 9 May 2022 20:13:17 -0400 (EDT)

branch: master
commit 3d69769b190673547d5ab1fa3fc6a86753b9f1a8
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Demonstrate that a default comparison tolerance works well
---
 ul_utilities.cpp      |  9 ++++-----
 ul_utilities_test.cpp | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/ul_utilities.cpp b/ul_utilities.cpp
index 2e8fa498..e8bae50c 100644
--- a/ul_utilities.cpp
+++ b/ul_utilities.cpp
@@ -121,10 +121,9 @@ currency max_modal_premium
     int64 irate = bourn_cast<int64>(std::nearbyint(rate * radix));
     // If the rate really has more than eight significant (non-erroneous)
     // digits, then treat them all as significant. In that case, there
-    // is no representation error to be removed. Here, 'tol' is just a
-    // guess; it may need refinement.
-    constexpr double tol = 1.0e-12;
-    if(!materially_equal(bourn_cast<double>(irate), rate * radix, tol))
+    // is no representation error to be removed. The accompanying unit
+    // test gives illustrative examples.
+    if(!materially_equal(bourn_cast<double>(irate), rate * radix))
         {
 #if 0
         // Enable this (including <iostream>) for research.
@@ -141,7 +140,7 @@ currency max_modal_premium
 #if 0
     // Enable this assertion, adjusting the tolerance (last) argument
     // p.r.n., if no table is allowed to have more than eight decimals.
-    LMI_ASSERT(materially_equal(bourn_cast<double>(irate), rate * radix, tol));
+    LMI_ASSERT(materially_equal(bourn_cast<double>(irate), rate * radix));
 #endif // 0
     // Multiply integer rate by integral-cents specamt.
     // Use a large integer type to avoid overflow.
diff --git a/ul_utilities_test.cpp b/ul_utilities_test.cpp
index 51a064eb..a7c07d9d 100644
--- a/ul_utilities_test.cpp
+++ b/ul_utilities_test.cpp
@@ -23,12 +23,46 @@
 
 #include "ul_utilities.hpp"
 
+#include "bourn_cast.hpp"
 #include "materially_equal.hpp"
 #include "round_to.hpp"
 #include "test_tools.hpp"
 
+#include <cfenv>                        // fesetround()
+#include <cmath>                        // nearbyint()
+#include <cstdint>                      // int64_t
+
 void test_max_modal_premium()
 {
+    auto test_excess_precision = [](double rate)
+        {
+        using int64 = std::int64_t;
+        constexpr int radix {100'000'000};
+        std::fesetround(FE_TONEAREST);
+        int64 irate = bourn_cast<int64>(std::nearbyint(rate * radix));
+        return !materially_equal(bourn_cast<double>(irate), rate * radix);
+        };
+    LMI_TEST(!test_excess_precision(0.0                    ));
+    LMI_TEST(!test_excess_precision(0.00000001             ));
+    LMI_TEST(!test_excess_precision(0.000000010000000000001));
+    LMI_TEST( test_excess_precision(0.00000001000000000001 ));
+    LMI_TEST( test_excess_precision(0.0000000100000000001  ));
+    LMI_TEST( test_excess_precision(0.000000010000000001   ));
+    LMI_TEST( test_excess_precision(0.00000001000000001    ));
+    LMI_TEST( test_excess_precision(0.0000000100000001     ));
+    LMI_TEST( test_excess_precision(0.000000010000001      ));
+    LMI_TEST(!test_excess_precision(0.999999990000000      ));
+    LMI_TEST(!test_excess_precision(0.999999990000001      ));
+    LMI_TEST(!test_excess_precision(0.99999999000001       ));
+    LMI_TEST(!test_excess_precision(0.9999999900001        ));
+    LMI_TEST( test_excess_precision(0.999999990001         ));
+    LMI_TEST( test_excess_precision(0.99999999001          ));
+    LMI_TEST( test_excess_precision(0.99999999999          ));
+    LMI_TEST( test_excess_precision(0.999999999999         ));
+    LMI_TEST(!test_excess_precision(0.9999999999999        ));
+    LMI_TEST(!test_excess_precision(0.99999999999999       ));
+    LMI_TEST(!test_excess_precision(0.999999999999999      ));
+
     round_to<double> const round_down(2, r_downward);
     round_to<double> const round_near(2, r_to_nearest);
     round_to<double> const round_not (2, r_not_at_all);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]