gnucash master: Multiple changes pushed

Mike Alexander mta at code.gnucash.org
Tue Aug 22 00:50:49 EDT 2017


Updated	 via  https://github.com/Gnucash/gnucash/commit/29a92431 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/57638161 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/00c7089e (commit)
	from  https://github.com/Gnucash/gnucash/commit/f5c86453 (commit)



commit 29a92431cb85b6454c106d824ed5265bb1547525
Author: Mike Alexander <mta at umich.edu>
Date:   Tue Aug 22 00:47:08 2017 -0400

    Fix sigfigs(n) rounding to work when the input is bigger tnan 10**n.
    
    For example rounding 1234567/1 to 6 significant figures would fail.

diff --git a/libgnucash/engine/gnc-numeric.cpp b/libgnucash/engine/gnc-numeric.cpp
index a75e212..0b7770a 100644
--- a/libgnucash/engine/gnc-numeric.cpp
+++ b/libgnucash/engine/gnc-numeric.cpp
@@ -300,7 +300,9 @@ GncNumeric::sigfigs_denom(unsigned figs) const noexcept
         ++digits;
         val /= 10;
     }
-    return not_frac ? powten(figs - digits - 1) : powten(figs + digits);
+    return not_frac ? 
+            powten(digits < figs ? figs - digits - 1 : 0) : 
+            powten(figs + digits);
 }
 
 std::string
diff --git a/libgnucash/engine/gnc-rational.cpp b/libgnucash/engine/gnc-rational.cpp
index 9c787a4..c534b8b 100644
--- a/libgnucash/engine/gnc-rational.cpp
+++ b/libgnucash/engine/gnc-rational.cpp
@@ -171,7 +171,9 @@ GncRational::sigfigs_denom(unsigned figs) const noexcept
         ++digits;
         val /= 10;
     }
-    return not_frac ? powten(figs - digits - 1) : powten(figs + digits);
+    return not_frac ? 
+            powten(digits < figs ? figs - digits - 1 : 0) : 
+            powten(figs + digits);
 }
 
 GncRational

commit 57638161f2ea6f042df6cf12edc8772e69d5a001
Author: Mike Alexander <mta at umich.edu>
Date:   Tue Aug 22 00:35:10 2017 -0400

    Fix numerator overflow constructing GncNumeric from 96.16

diff --git a/libgnucash/engine/gnc-numeric.cpp b/libgnucash/engine/gnc-numeric.cpp
index 8e79cfb..a75e212 100644
--- a/libgnucash/engine/gnc-numeric.cpp
+++ b/libgnucash/engine/gnc-numeric.cpp
@@ -89,14 +89,22 @@ GncNumeric::GncNumeric(double d) : m_num(0), m_den(1)
         msg << "Unable to construct a GncNumeric from " << d << ".\n";
         throw std::invalid_argument(msg.str());
     }
-    constexpr auto max_denom = INT64_MAX / 10;
+    constexpr auto max_num = static_cast<double>(INT64_MAX);
     auto logval = log10(fabs(d));
     int64_t den;
+    uint8_t den_digits;
     if (logval > 0.0)
-        den = powten((max_leg_digits + 1) - static_cast<int>(floor(logval) + 1.0));
+        den_digits = (max_leg_digits + 1) - static_cast<int>(floor(logval) + 1.0);
     else
-        den = powten(max_leg_digits);
-    auto num = static_cast<int64_t>(floor(static_cast<double>(den) * d));
+        den_digits = max_leg_digits;
+    den = powten(den_digits);
+    auto num_d = static_cast<double>(den) * d;
+    while (fabs(num_d) > max_num && den_digits > 1)
+    {
+        den = powten(--den_digits);
+        num_d = static_cast<double>(den) * d;
+    }
+    auto num = static_cast<int64_t>(floor(num_d));
 
     if (num == 0)
         return;

commit 00c7089ecb282db81fd8681d5ef64bc88833cf0e
Author: Mike Alexander <mta at umich.edu>
Date:   Sat Apr 15 02:08:16 2017 -0400

    Add tests for converting doubles 96.16 and 9616000000.0 to GncNumeric.

diff --git a/libgnucash/engine/test/test-numeric.cpp b/libgnucash/engine/test/test-numeric.cpp
index 04a3359..2f284f7 100644
--- a/libgnucash/engine/test/test-numeric.cpp
+++ b/libgnucash/engine/test/test-numeric.cpp
@@ -370,6 +370,22 @@ check_double (void)
                                           GNC_HOW_RND_ROUND),
                     val, "expected %s = %s double 6 figs");
 
+    check_unary_op (gnc_numeric_eq,
+                    gnc_numeric_create (961600000, 10000000),
+                    double_to_gnc_numeric(96.16,
+                                          GNC_DENOM_AUTO,
+                                          GNC_HOW_DENOM_SIGFIGS(9) |
+                                          GNC_HOW_RND_ROUND),
+                    val, "expected %s = %s GncNumeric from 96.16");
+
+    check_unary_op (gnc_numeric_eq,
+                    gnc_numeric_create (9616000000, 1),
+                    double_to_gnc_numeric(9616000000.0,
+                                          GNC_DENOM_AUTO,
+                                          GNC_HOW_DENOM_SIGFIGS(9) |
+                                          GNC_HOW_RND_ROUND),
+                    val, "expected %s = %s GncNumeric from 9616000000.0");
+
     flo = gnc_numeric_to_double(gnc_numeric_create(7, 16));
     do_test ((0.4375 == flo), "float pt conversion");
 }



Summary of changes:
 libgnucash/engine/gnc-numeric.cpp       | 20 +++++++++++++++-----
 libgnucash/engine/gnc-rational.cpp      |  4 +++-
 libgnucash/engine/test/test-numeric.cpp | 16 ++++++++++++++++
 3 files changed, 34 insertions(+), 6 deletions(-)



More information about the gnucash-changes mailing list