r15484 - gnucash/trunk - Add lib/libc/pow.h to avoid calculation errors on Windows.

Andreas Köhler andi5 at cvs.gnucash.org
Wed Jan 31 20:08:06 EST 2007


Author: andi5
Date: 2007-01-31 20:08:05 -0500 (Wed, 31 Jan 2007)
New Revision: 15484
Trac: http://svn.gnucash.org/trac/changeset/15484

Added:
   gnucash/trunk/lib/libc/pow.h
Modified:
   gnucash/trunk/lib/libc/Makefile.am
   gnucash/trunk/lib/libqof/qof/gnc-numeric.c
   gnucash/trunk/src/app-utils/Makefile.am
   gnucash/trunk/src/app-utils/gnc-ui-util.c
   gnucash/trunk/src/calculation/Makefile.am
   gnucash/trunk/src/calculation/fin.c
   gnucash/trunk/src/gnome-utils/dialog-account.c
Log:
Add lib/libc/pow.h to avoid calculation errors on Windows.

If the return value of pow is not saved in a double but rather used for
other calculations or casts, results can be bad, like pow(10, 2) being
99 instead of 100. Wrap pow and store the return value first before
continuing.


Modified: gnucash/trunk/lib/libc/Makefile.am
===================================================================
--- gnucash/trunk/lib/libc/Makefile.am	2007-02-01 01:00:31 UTC (rev 15483)
+++ gnucash/trunk/lib/libc/Makefile.am	2007-02-01 01:08:05 UTC (rev 15484)
@@ -2,7 +2,7 @@
 
 # All header files must be listed.
 noinst_HEADERS = \
-  localtime_r.h setenv.h strptime.h
+  localtime_r.h setenv.h strptime.h pow.h
 
 # No sources should be listed.
 libc_missing_la_SOURCES = libc-missing-noop.c

Added: gnucash/trunk/lib/libc/pow.h
===================================================================
--- gnucash/trunk/lib/libc/pow.h	2007-02-01 01:00:31 UTC (rev 15483)
+++ gnucash/trunk/lib/libc/pow.h	2007-02-01 01:08:05 UTC (rev 15484)
@@ -0,0 +1,58 @@
+/********************************************************************\
+ * pow.h -- pow wrapper for MinGW systems                           *
+ * Copyright (C) 2007 Andreas Koehler <andi5.py at gmx.net>            *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef __POW_H__
+#define __POW_H__
+
+#include <math.h>
+
+/* From MinGW, math.h: */
+
+/* Excess precision when using a 64-bit mantissa for FPU math ops can
+ * cause unexpected results with some of the MSVCRT math functions.
+ * For example, unless the function return value is stored (truncating
+ * to 53-bit mantissa), calls to pow with both x and y as integral
+ * values sometimes produce a non-integral result. */
+
+#define __DEFINE_FLOAT_STORE_MATHFN_D1(fn1)	\
+static __inline__ double			\
+__float_store_ ## fn1 (double x)		\
+{						\
+   __volatile__ double res = (fn1) (x);		\
+  return res;					\
+}
+
+#define __DEFINE_FLOAT_STORE_MATHFN_D2(fn2)	\
+static __inline__ double			\
+__float_store_ ## fn2 (double x, double y)	\
+{						\
+  __volatile__ double res = (fn2) (x, y);	\
+  return res;					\
+}
+
+#undef pow
+
+/* Define the ___float_store_pow function and use it instead of pow(). */
+__DEFINE_FLOAT_STORE_MATHFN_D2 (pow)
+#define pow __float_store_pow
+
+#endif /* __POW_H__ */

Modified: gnucash/trunk/lib/libqof/qof/gnc-numeric.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-numeric.c	2007-02-01 01:00:31 UTC (rev 15483)
+++ gnucash/trunk/lib/libqof/qof/gnc-numeric.c	2007-02-01 01:08:05 UTC (rev 15484)
@@ -26,6 +26,9 @@
 
 #include <glib.h>
 #include <math.h>
+#ifdef G_OS_WIN32
+#include <pow.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

Modified: gnucash/trunk/src/app-utils/Makefile.am
===================================================================
--- gnucash/trunk/src/app-utils/Makefile.am	2007-02-01 01:00:31 UTC (rev 15483)
+++ gnucash/trunk/src/app-utils/Makefile.am	2007-02-01 01:08:05 UTC (rev 15484)
@@ -3,6 +3,7 @@
 pkglib_LTLIBRARIES = libgncmod-app-utils.la
 
 AM_CFLAGS = \
+  -I$(top_srcdir)/lib/libc \
   -I${top_srcdir}/src \
   -I${top_builddir}/src \
   -I${top_srcdir}/src/gnc-module \

Modified: gnucash/trunk/src/app-utils/gnc-ui-util.c
===================================================================
--- gnucash/trunk/src/app-utils/gnc-ui-util.c	2007-02-01 01:00:31 UTC (rev 15483)
+++ gnucash/trunk/src/app-utils/gnc-ui-util.c	2007-02-01 01:08:05 UTC (rev 15484)
@@ -30,6 +30,9 @@
 #include <limits.h>
 #include <locale.h>
 #include <math.h>
+#ifdef G_OS_WIN32
+#include <pow.h>
+#endif
 #include <stdarg.h>
 #include <stdlib.h>
 #include <stdio.h>

Modified: gnucash/trunk/src/calculation/Makefile.am
===================================================================
--- gnucash/trunk/src/calculation/Makefile.am	2007-02-01 01:00:31 UTC (rev 15483)
+++ gnucash/trunk/src/calculation/Makefile.am	2007-02-01 01:08:05 UTC (rev 15484)
@@ -29,6 +29,7 @@
   numeric_ops.h
 
 AM_CFLAGS = \
+  -I${top_srcdir}/lib/libc \
   -I${top_srcdir}/src \
   -I${top_srcdir}/src/gnc-module \
   ${GUILE_INCS} \

Modified: gnucash/trunk/src/calculation/fin.c
===================================================================
--- gnucash/trunk/src/calculation/fin.c	2007-02-01 01:00:31 UTC (rev 15483)
+++ gnucash/trunk/src/calculation/fin.c	2007-02-01 01:08:05 UTC (rev 15484)
@@ -1196,10 +1196,13 @@
 
 #include <time.h>
 #include <stdio.h>
+#include <glib.h>
 #include <math.h>
+#ifdef G_OS_WIN32
+#include <pow.h>
+#endif
 #include <string.h>
 #include <stdlib.h>
-#include <glib.h>
 
 #define FIN_STATICS
 #include "finvar.h"

Modified: gnucash/trunk/src/gnome-utils/dialog-account.c
===================================================================
--- gnucash/trunk/src/gnome-utils/dialog-account.c	2007-02-01 01:00:31 UTC (rev 15483)
+++ gnucash/trunk/src/gnome-utils/dialog-account.c	2007-02-01 01:08:05 UTC (rev 15484)
@@ -27,6 +27,9 @@
 #include <gnome.h>
 #include <glib/gi18n.h>
 #include <math.h>
+#ifdef G_OS_WIN32
+#include <pow.h>
+#endif
 #include <string.h>
 
 #include "Transaction.h"



More information about the gnucash-changes mailing list