mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Cygwin and Mingw floating-point fixes.
Deal with silent-underflow errors in float4 for cygwin and mingw by using our strtof() wrapper; deal with misrounding errors by adding them to the resultmap. Some slight reorganization of declarations was done to avoid duplicating material between cygwin.h and win32_port.h. While here, remove from the resultmap all references to float8-small-is-zero; inspection of cygwin output suggests it's no longer required there, and the freebsd/netbsd/openbsd entries should no longer be necessary (these date back to c. 2000). This commit doesn't remove the file itself nor the documentation references for it; that will happen in a subsequent commit if all goes well.
This commit is contained in:
19
configure
vendored
19
configure
vendored
@ -15828,6 +15828,25 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case $host_os in
|
||||||
|
# Cygwin and (apparently, based on test results) Mingw both
|
||||||
|
# have a broken strtof(), so substitute the same replacement
|
||||||
|
# code we use with VS2013. That's not a perfect fix, since
|
||||||
|
# (unlike with VS2013) it doesn't avoid double-rounding, but
|
||||||
|
# we have no better options. To get that, though, we have to
|
||||||
|
# force the file to be compiled despite HAVE_STRTOF.
|
||||||
|
mingw*|cygwin*)
|
||||||
|
case " $LIBOBJS " in
|
||||||
|
*" strtof.$ac_objext "* ) ;;
|
||||||
|
*) LIBOBJS="$LIBOBJS strtof.$ac_objext"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: On $host_os we will use our strtof wrapper." >&5
|
||||||
|
$as_echo "$as_me: On $host_os we will use our strtof wrapper." >&6;}
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
case $host_os in
|
case $host_os in
|
||||||
|
|
||||||
# Windows uses a specialised env handler
|
# Windows uses a specialised env handler
|
||||||
|
13
configure.in
13
configure.in
@ -1715,6 +1715,19 @@ AC_REPLACE_FUNCS(m4_normalize([
|
|||||||
strtof
|
strtof
|
||||||
]))
|
]))
|
||||||
|
|
||||||
|
case $host_os in
|
||||||
|
# Cygwin and (apparently, based on test results) Mingw both
|
||||||
|
# have a broken strtof(), so substitute the same replacement
|
||||||
|
# code we use with VS2013. That's not a perfect fix, since
|
||||||
|
# (unlike with VS2013) it doesn't avoid double-rounding, but
|
||||||
|
# we have no better options. To get that, though, we have to
|
||||||
|
# force the file to be compiled despite HAVE_STRTOF.
|
||||||
|
mingw*|cygwin*)
|
||||||
|
AC_LIBOBJ([strtof])
|
||||||
|
AC_MSG_NOTICE([On $host_os we will use our strtof wrapper.])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
case $host_os in
|
case $host_os in
|
||||||
|
|
||||||
# Windows uses a specialised env handler
|
# Windows uses a specialised env handler
|
||||||
|
@ -385,6 +385,11 @@ extern int isinf(double x);
|
|||||||
extern float strtof(const char *nptr, char **endptr);
|
extern float strtof(const char *nptr, char **endptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_BUGGY_STRTOF
|
||||||
|
extern float pg_strtof(const char *nptr, char **endptr);
|
||||||
|
#define strtof(a,b) (pg_strtof((a),(b)))
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_MKDTEMP
|
#ifndef HAVE_MKDTEMP
|
||||||
extern char *mkdtemp(char *path);
|
extern char *mkdtemp(char *path);
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,3 +16,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PGDLLEXPORT
|
#define PGDLLEXPORT
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cygwin has a strtof() which is literally just (float)strtod(), which means
|
||||||
|
* we get misrounding _and_ silent over/underflow. Using our wrapper doesn't
|
||||||
|
* fix the misrounding but does fix the error checks, which cuts down on the
|
||||||
|
* number of test variant files needed.
|
||||||
|
*/
|
||||||
|
#define HAVE_BUGGY_STRTOF 1
|
||||||
|
@ -510,16 +510,23 @@ typedef unsigned short mode_t;
|
|||||||
#define isnan(x) _isnan(x)
|
#define isnan(x) _isnan(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || \
|
||||||
|
defined(__MINGW32__) || defined(__MINGW64__)
|
||||||
/*
|
/*
|
||||||
* VS2013 has a strtof() that seems to give correct answers for valid input,
|
* VS2013 has a strtof() that seems to give correct answers for valid input,
|
||||||
* even on the rounding edge cases, but which doesn't handle out-of-range
|
* even on the rounding edge cases, but which doesn't handle out-of-range
|
||||||
* input correctly. Work around that.
|
* input correctly. Work around that.
|
||||||
|
*
|
||||||
|
* Mingw claims to have a strtof, and my reading of its source code suggests
|
||||||
|
* that it ought to work (and not need this hack), but the regression test
|
||||||
|
* results disagree with me; whether this is a version issue or not is not
|
||||||
|
* clear. However, using our wrapper (and the misrounded-input variant file,
|
||||||
|
* already required for supporting ancient systems) can't make things any
|
||||||
|
* worse, except for a tiny performance loss when reading zeros.
|
||||||
|
*
|
||||||
|
* See also cygwin.h for another instance of this.
|
||||||
*/
|
*/
|
||||||
#define HAVE_BUGGY_WINDOWS_STRTOF 1
|
#define HAVE_BUGGY_STRTOF 1
|
||||||
extern float pg_strtof(const char *nptr, char **endptr);
|
|
||||||
#define strtof(a,b) (pg_strtof((a),(b)))
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Pulled from Makefile.port in MinGW */
|
/* Pulled from Makefile.port in MinGW */
|
||||||
|
@ -52,7 +52,7 @@ strtof(const char *nptr, char **endptr)
|
|||||||
return fresult;
|
return fresult;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif HAVE_BUGGY_WINDOWS_STRTOF
|
#elif HAVE_BUGGY_STRTOF
|
||||||
/*
|
/*
|
||||||
* On Windows, there's a slightly different problem: VS2013 has a strtof()
|
* On Windows, there's a slightly different problem: VS2013 has a strtof()
|
||||||
* that returns the correct results for valid input, but may fail to report an
|
* that returns the correct results for valid input, but may fail to report an
|
||||||
@ -62,6 +62,14 @@ strtof(const char *nptr, char **endptr)
|
|||||||
* well, so prefer to round the strtod() result in such cases. (Normally we'd
|
* well, so prefer to round the strtod() result in such cases. (Normally we'd
|
||||||
* just say "too bad" if strtof() doesn't support subnormals, but since we're
|
* just say "too bad" if strtof() doesn't support subnormals, but since we're
|
||||||
* already in here fixing stuff, we might as well do the best fix we can.)
|
* already in here fixing stuff, we might as well do the best fix we can.)
|
||||||
|
*
|
||||||
|
* Cygwin has a strtof() which is literally just (float)strtod(), which means
|
||||||
|
* we can't avoid the double-rounding problem; but using this wrapper does get
|
||||||
|
* us proper over/underflow checks. (Also, if they fix their strtof(), the
|
||||||
|
* wrapper doesn't break anything.)
|
||||||
|
*
|
||||||
|
* Test results on Mingw suggest that it has the same problem, though looking
|
||||||
|
* at the code I can't figure out why.
|
||||||
*/
|
*/
|
||||||
float
|
float
|
||||||
pg_strtof(const char *nptr, char **endptr)
|
pg_strtof(const char *nptr, char **endptr)
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
float8:out:i.86-.*-freebsd=float8-small-is-zero.out
|
float4:out:.*-.*-cygwin.*=float4-misrounded-input.out
|
||||||
float8:out:i.86-.*-openbsd=float8-small-is-zero.out
|
float4:out:.*-.*-mingw.*=float4-misrounded-input.out
|
||||||
float8:out:i.86-.*-netbsd=float8-small-is-zero.out
|
|
||||||
float8:out:m68k-.*-netbsd=float8-small-is-zero.out
|
|
||||||
float8:out:i.86-pc-cygwin=float8-small-is-zero.out
|
|
||||||
float4:out:hppa.*-hp-hpux10.*=float4-misrounded-input.out
|
float4:out:hppa.*-hp-hpux10.*=float4-misrounded-input.out
|
||||||
|
Reference in New Issue
Block a user