r23720 - gnucash/trunk/src/libqof/qof - Replace pow(10, foo) with array dereference

John Ralls jralls at code.gnucash.org
Sun Jan 19 16:22:02 EST 2014


Author: jralls
Date: 2014-01-19 16:22:01 -0500 (Sun, 19 Jan 2014)
New Revision: 23720
Trac: http://svn.gnucash.org/trac/changeset/23720

Modified:
   gnucash/trunk/src/libqof/qof/gnc-numeric.c
Log:
Replace pow(10, foo) with array dereference

Aside from being much faster, Windows was occasionally returning
e.g. 99 instead of 100 for pow(10, 2).  This stops that and thus
fixes:
Bug 721447 - Entries with values of ,50 are imported as ,51
Bug 721825 - Online prices displayed as unreadable fractions in 2.6.0

Modified: gnucash/trunk/src/libqof/qof/gnc-numeric.c
===================================================================
--- gnucash/trunk/src/libqof/qof/gnc-numeric.c	2014-01-19 20:52:46 UTC (rev 23719)
+++ gnucash/trunk/src/libqof/qof/gnc-numeric.c	2014-01-19 21:22:01 UTC (rev 23720)
@@ -26,11 +26,6 @@
 
 #include <glib.h>
 #include <math.h>
-#if defined(G_OS_WIN32) && !defined(_MSC_VER)
-# ifdef HAVE_POW_H
-#   include <pow.h>
-# endif
-#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -44,7 +39,20 @@
 #include "qofmath128.c"
 
 /* static short module = MOD_ENGINE; */
+static const gint64 pten[] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
+			       10000000, 100000000, 1000000000, 10000000000,
+			       100000000000, 1000000000000, 10000000000000,
+			       100000000000000, 10000000000000000};
+#define POWTEN_OVERFLOW -5
 
+static inline gint64
+powten (int exp)
+{
+    if (exp > 16 || exp < -16)
+	return POWTEN_OVERFLOW;
+    return exp < 0 ? -pten[-exp] : pten[exp];
+}
+
 gint64
 pwr64 (gint64 op, int exp)
 {
@@ -819,18 +827,9 @@
             }
             sigfigs  = GNC_HOW_GET_SIGFIGS(how);
 
-            if (fabs(sigfigs - logratio) > 18)
+            if ((denom = powten (sigfigs - logratio)) == POWTEN_OVERFLOW)
                 return gnc_numeric_error(GNC_ERROR_OVERFLOW);
 
-            if (sigfigs - logratio >= 0)
-            {
-                denom    = (gint64)(pow(10, sigfigs - logratio));
-            }
-            else
-            {
-                denom    = -((gint64)(pow(10, logratio - sigfigs)));
-            }
-
             how = how & ~GNC_HOW_DENOM_SIGFIG & ~GNC_NUMERIC_SIGFIGS_MASK;
             break;
 
@@ -1153,7 +1152,6 @@
 #ifdef _MSC_VER
 # define rint /* */
 #endif
-
 gnc_numeric
 double_to_gnc_numeric(double in, gint64 denom, gint how)
 {
@@ -1177,14 +1175,8 @@
                         (floor(logval) + 1.0) : (ceil(logval)));
         }
         sigfigs  = GNC_HOW_GET_SIGFIGS(how);
-        if (sigfigs - logval >= 0)
-        {
-            denom    = (gint64)(pow(10, sigfigs - logval));
-        }
-        else
-        {
-            denom    = -((gint64)(pow(10, logval - sigfigs)));
-        }
+	if ((denom = powten (sigfigs - logval)) == POWTEN_OVERFLOW)
+            return gnc_numeric_error(GNC_ERROR_OVERFLOW);
 
         how =  how & ~GNC_HOW_DENOM_SIGFIG & ~GNC_NUMERIC_SIGFIGS_MASK;
     }



More information about the gnucash-changes mailing list