lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master f2a2eff 5/6: Factor out the tricky part of le


From: Greg Chicares
Subject: [lmi-commits] [lmi] master f2a2eff 5/6: Factor out the tricky part of ledger scaling, to permit unit testing
Date: Thu, 15 Mar 2018 20:12:22 -0400 (EDT)

branch: master
commit f2a2effafa7ea813c61f9088ea9c3b93865db96c
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Factor out the tricky part of ledger scaling, to permit unit testing
---
 ledger_base.cpp | 28 ++--------------------------
 miscellany.cpp  | 34 +++++++++++++++++++++++++++++++++-
 miscellany.hpp  |  2 ++
 3 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/ledger_base.cpp b/ledger_base.cpp
index b01ca2a..0e88f2b 100644
--- a/ledger_base.cpp
+++ b/ledger_base.cpp
@@ -27,12 +27,11 @@
 #include "assert_lmi.hpp"
 #include "crc32.hpp"
 #include "et_vector.hpp"
-#include "miscellany.hpp"               // minmax
+#include "miscellany.hpp"               // minmax, scale_power()
 #include "stl_extensions.hpp"           // nonstd::power()
 #include "value_cast.hpp"
 
 #include <algorithm>                    // max(), min()
-#include <cmath>                        // floor(), log10()
 #include <stdexcept>                    // logic_error
 
 //============================================================================
@@ -319,30 +318,7 @@ int LedgerBase::DetermineScalePower(int max_power) const
         max_value = std::max(max_value, extrema.maximum());
         }
 
-    // If minimum value is negative, it needs an extra character to
-    // display the minus sign. So it needs as many characters as
-    // ten times its absolute value.
-    double widest = std::max
-        (min_value * -10
-        ,max_value
-        );
-
-    if(0 == widest || widest < nonstd::power(10.0, max_power))
-        {
-        return 0;
-        }
-
-// PDF !! This seems not to be rigorously correct: $999,999,999.99 is
-// less than one billion, but rounds to $1,000,000,000.
-    double d = std::log10(widest);
-    d = std::floor(d / 3.0);
-    int k = 3 * static_cast<int>(d);
-    k = k - 6;
-
-    LMI_ASSERT(0 <= k);
-    LMI_ASSERT(k <= 18);
-
-    return k;
+    return scale_power(max_power, min_value, max_value);
 }
 
 namespace
diff --git a/miscellany.cpp b/miscellany.cpp
index ebdf300..06fa1f5 100644
--- a/miscellany.cpp
+++ b/miscellany.cpp
@@ -25,8 +25,10 @@
 
 #include "alert.hpp"
 #include "assert_lmi.hpp"
+#include "stl_extensions.hpp"           // nonstd::power()
 
-#include <algorithm>                    // equal()
+#include <algorithm>                    // equal(), max()
+#include <cmath>                        // floor(), log10()
 #include <ctime>
 #include <fstream>
 #include <istream>
@@ -69,6 +71,36 @@ bool files_are_identical(std::string const& file0, 
std::string const& file1)
     return streams_are_identical(ifs0, ifs1);
 }
 
+/// Triple-power-of-ten scaling to keep extremum < 10^max_power.
+
+int scale_power(int max_power, double min_value, double max_value)
+{
+    // If minimum value is negative, it needs an extra character to
+    // display the minus sign. So it needs as many characters as
+    // ten times its absolute value.
+    double widest = std::max
+        (min_value * -10
+        ,max_value
+        );
+
+    if(0 == widest || widest < nonstd::power(10.0, max_power))
+        {
+        return 0;
+        }
+
+// PDF !! This seems not to be rigorously correct: $999,999,999.99 is
+// less than one billion, but rounds to $1,000,000,000.
+    double d = std::log10(widest);
+    d = std::floor(d / 3.0);
+    int k = 3 * static_cast<int>(d);
+    k = k - 6;
+
+    LMI_ASSERT(0 <= k);
+    LMI_ASSERT(k <= 18);
+
+    return k;
+}
+
 /// Return the number of newline characters in a string.
 
 std::size_t count_newlines(std::string const& s)
diff --git a/miscellany.hpp b/miscellany.hpp
index 170b497..15bc360 100644
--- a/miscellany.hpp
+++ b/miscellany.hpp
@@ -93,6 +93,8 @@ template<typename T> bool operator<=(T t, minmax<T> m) 
{return t <= m.minimum();
 template<typename T> bool operator< (minmax<T> m, T t) {return m.maximum() <  
t;}
 template<typename T> bool operator<=(minmax<T> m, T t) {return m.maximum() <= 
t;}
 
+int LMI_SO scale_power(int max_power, double min_value, double max_value);
+
 std::size_t LMI_SO count_newlines(std::string const&);
 
 std::vector<std::string> LMI_SO split_into_lines(std::string const&);



reply via email to

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