From c71c7ecd24c7d8e75e5f5060e1ba15338fa2f29a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=B6hler?= Date: Thu, 1 Feb 2007 01:08:05 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@15484 57a11ea4-9604-0410-9ed3-97b8803252fd --- lib/libc/Makefile.am | 2 +- lib/libc/pow.h | 58 ++++++++++++++++++++++++++++++++ lib/libqof/qof/gnc-numeric.c | 3 ++ src/app-utils/Makefile.am | 1 + src/app-utils/gnc-ui-util.c | 3 ++ src/calculation/Makefile.am | 1 + src/calculation/fin.c | 5 ++- src/gnome-utils/dialog-account.c | 3 ++ 8 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 lib/libc/pow.h diff --git a/lib/libc/Makefile.am b/lib/libc/Makefile.am index 92214b48a6..67a4b35a73 100644 --- a/lib/libc/Makefile.am +++ b/lib/libc/Makefile.am @@ -2,7 +2,7 @@ noinst_LTLIBRARIES = libc-missing.la # 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 diff --git a/lib/libc/pow.h b/lib/libc/pow.h new file mode 100644 index 0000000000..9ca3e3dcf0 --- /dev/null +++ b/lib/libc/pow.h @@ -0,0 +1,58 @@ +/********************************************************************\ + * pow.h -- pow wrapper for MinGW systems * + * Copyright (C) 2007 Andreas Koehler * + * * + * 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@gnu.org * +\********************************************************************/ + +#ifndef __POW_H__ +#define __POW_H__ + +#include + +/* 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__ */ diff --git a/lib/libqof/qof/gnc-numeric.c b/lib/libqof/qof/gnc-numeric.c index 235848b1de..319a31ccb5 100644 --- a/lib/libqof/qof/gnc-numeric.c +++ b/lib/libqof/qof/gnc-numeric.c @@ -26,6 +26,9 @@ #include #include +#ifdef G_OS_WIN32 +#include +#endif #include #include #include diff --git a/src/app-utils/Makefile.am b/src/app-utils/Makefile.am index e5e5905453..23af03c07d 100644 --- a/src/app-utils/Makefile.am +++ b/src/app-utils/Makefile.am @@ -3,6 +3,7 @@ SUBDIRS = . test 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 \ diff --git a/src/app-utils/gnc-ui-util.c b/src/app-utils/gnc-ui-util.c index 7adb827927..86f49ae10f 100644 --- a/src/app-utils/gnc-ui-util.c +++ b/src/app-utils/gnc-ui-util.c @@ -30,6 +30,9 @@ #include #include #include +#ifdef G_OS_WIN32 +#include +#endif #include #include #include diff --git a/src/calculation/Makefile.am b/src/calculation/Makefile.am index 23eb8630bf..5d27d580a6 100644 --- a/src/calculation/Makefile.am +++ b/src/calculation/Makefile.am @@ -29,6 +29,7 @@ EXTRA_DIST = \ numeric_ops.h AM_CFLAGS = \ + -I${top_srcdir}/lib/libc \ -I${top_srcdir}/src \ -I${top_srcdir}/src/gnc-module \ ${GUILE_INCS} \ diff --git a/src/calculation/fin.c b/src/calculation/fin.c index c10eb4ab78..1e3e1b0fce 100644 --- a/src/calculation/fin.c +++ b/src/calculation/fin.c @@ -1196,10 +1196,13 @@ #include #include +#include #include +#ifdef G_OS_WIN32 +#include +#endif #include #include -#include #define FIN_STATICS #include "finvar.h" diff --git a/src/gnome-utils/dialog-account.c b/src/gnome-utils/dialog-account.c index e39df5204b..f8d3628672 100644 --- a/src/gnome-utils/dialog-account.c +++ b/src/gnome-utils/dialog-account.c @@ -27,6 +27,9 @@ #include #include #include +#ifdef G_OS_WIN32 +#include +#endif #include #include "Transaction.h"