lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master 3d9cefe7 1/6: Improve documentation; tighten


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 3d9cefe7 1/6: Improve documentation; tighten an error tolerance
Date: Sun, 1 May 2022 16:54:19 -0400 (EDT)

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

    Improve documentation; tighten an error tolerance
    
    Incidentally regularized indentation.
---
 financial.hpp      | 20 ++++++++++++++------
 financial_test.cpp | 21 ++++++++++++++++-----
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/financial.hpp b/financial.hpp
index 7b18939b..075ed601 100644
--- a/financial.hpp
+++ b/financial.hpp
@@ -46,15 +46,12 @@ class calendar_date;
 // When no root is bracketed, -100% is always conservative enough;
 // but if a root is known to exceed the a priori upper bound, then
 // perhaps that upper bound could be returned instead.
-//
-// Is it really advantageous to use long double? Why not use a
-// template type argument instead?
 
 template<typename InputIterator>
 long double fv
     (InputIterator first
     ,InputIterator last
-    ,long double i
+    ,long double   i
     )
 {
     if(first == last)
@@ -74,6 +71,17 @@ long double fv
     return z;
 }
 
+/// IRR: internal rate of return
+///
+/// Not intended for direct use; prefer the provided cover functions.
+///
+/// Implemented in terms of 'long double' rather than 'double', even
+/// for x86_64, which normally favors 'double'--see:
+///   https://lists.nongnu.org/archive/html/lmi/2022-04/msg00004.html
+///   - it's more accurate for x86_64, by two orders of magnitude; and
+///   - it's as fast for x86_64, and maybe faster for i686 (x87); and
+///   - the resulting NPV is identical across architectures.
+
 template<typename InputIterator>
 class irr_helper
 {
@@ -134,8 +142,8 @@ template<typename InputIterator>
 long double irr
     (InputIterator first
     ,InputIterator last
-    ,long double x
-    ,int decimals
+    ,long double   x
+    ,int           decimals
     )
 {
     return irr_helper<InputIterator>(first, last, x, decimals)();
diff --git a/financial_test.cpp b/financial_test.cpp
index 41c8440e..f3554b07 100644
--- a/financial_test.cpp
+++ b/financial_test.cpp
@@ -44,7 +44,7 @@ template<typename InputIterator>
 long double pv
     (InputIterator first
     ,InputIterator last
-    ,long double i
+    ,long double   i
     )
 {
     if(first == last)
@@ -186,10 +186,21 @@ int test_main(int, char*[])
     // For any stream, NPV at the IRR rate should ideally be zero.
     std::vector<double> q{p};
     q.push_back(-b.back());
-    // This NPV is -9.777068044058979E-12 in a gnumeric spreadsheet,
-    // versus -9.86988e-014 with MinGW-w64 gcc-6.3.0
-    // versus  3.6593e-013  with i686-w64-mingw32 gcc-10.0
-    LMI_TEST(std::fabs(pv(q.begin(), q.end(), results.back())) <= 1e-12);
+    // On a 2.4GHz E5-2630 v3, on 2022-04-30, this NPV
+//  std::cout << pv(q.begin(), q.end(), results.back()) << std::endl;
+    // is
+    //        -9.77707E-12 in gnumeric,
+    // versus, for this 'long double' implementation:
+    //        -9.86988e-14 i686-w64-mingw32    gcc-10
+    //        -9.86988e-14 x86_64-w64-mingw32  gcc-10
+    //        -9.86988e-14 x86_64-pc-linux-gnu gcc-11.2.0
+    // versus, for an alternative implementation:
+    //   https://lists.nongnu.org/archive/html/lmi/2022-04/msg00004.html
+    // in terms of 'double':
+    //        -9.86988e-14 i686-w64-mingw32    gcc-10
+    //        -9.77707e-12 x86_64-w64-mingw32  gcc-10
+    //        -9.77707e-12 x86_64-pc-linux-gnu gcc-11.2.0
+    LMI_TEST(std::fabs(pv(q.begin(), q.end(), results.back())) <= 1e-13);
 
     // Trivially, NPV at 0% interest is summation.
     LMI_TEST(materially_equal(-4950.0L, pv(q.begin(), q.end(), 0.0)));



reply via email to

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