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
This commit is contained in:
Andreas Köhler 2007-02-01 01:08:05 +00:00
parent d719ce6cc2
commit c71c7ecd24
8 changed files with 74 additions and 2 deletions

View File

@ -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

58
lib/libc/pow.h Normal file
View File

@ -0,0 +1,58 @@
/********************************************************************\
* pow.h -- pow wrapper for MinGW systems *
* Copyright (C) 2007 Andreas Koehler <andi5.py@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@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__ */

View File

@ -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>

View File

@ -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 \

View File

@ -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>

View File

@ -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} \

View File

@ -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"

View File

@ -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"