aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/float.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-03-15 03:29:22 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-03-15 03:29:22 +0000
commit1bc2d544b979164a276f9e6052f0b6d23af59b60 (patch)
tree5373cea0da5a2587783dd5b805c90427143c7555 /src/backend/utils/adt/float.c
parent89ab5c4abf48de8156b9284dda869f9ea2b2ad44 (diff)
downloadpostgresql-1bc2d544b979164a276f9e6052f0b6d23af59b60.tar.gz
postgresql-1bc2d544b979164a276f9e6052f0b6d23af59b60.zip
Localize our dependencies on the way to create NAN or INFINITY.
Per recent proposal to pghackers.
Diffstat (limited to 'src/backend/utils/adt/float.c')
-rw-r--r--src/backend/utils/adt/float.c99
1 files changed, 80 insertions, 19 deletions
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index 9e078bfb349..bdedd83e6e3 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.100 2004/03/14 05:22:52 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.101 2004/03/15 03:29:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -54,9 +54,8 @@
#include <ctype.h>
#include <errno.h>
-#include <float.h> /* faked on sunos4 */
+#include <float.h>
#include <math.h>
-
#include <limits.h>
/* for finite() on Solaris */
#ifdef HAVE_IEEEFP_H
@@ -70,19 +69,11 @@
#include "utils/builtins.h"
-#ifndef HAVE_CBRT
-static double cbrt(double x);
-#endif /* HAVE_CBRT */
-
#ifndef M_PI
/* from my RH5.2 gcc math.h file - thomas 2000-04-03 */
#define M_PI 3.14159265358979323846
#endif
-#ifndef NAN
-#define NAN (0.0/0.0)
-#endif
-
#ifndef SHRT_MAX
#define SHRT_MAX 32767
#endif
@@ -109,9 +100,78 @@ int extra_float_digits = 0; /* Added to DBL_DIG or FLT_DIG */
static void CheckFloat4Val(double val);
static void CheckFloat8Val(double val);
-static int is_infinite(double val);
static int float4_cmp_internal(float4 a, float4 b);
static int float8_cmp_internal(float8 a, float8 b);
+#ifndef HAVE_CBRT
+static double cbrt(double x);
+#endif /* HAVE_CBRT */
+
+
+/*
+ * Routines to provide reasonably platform-independent handling of
+ * infinity and NaN. We assume that isinf() and isnan() are available
+ * and work per spec. (On some platforms, we have to supply our own;
+ * see src/port.) However, generating an Infinity or NaN in the first
+ * place is less well standardized; pre-C99 systems tend not to have C99's
+ * INFINITY and NAN macros. We centralize our workarounds for this here.
+ */
+
+double
+get_float8_infinity(void)
+{
+#ifdef INFINITY
+ /* C99 standard way */
+ return (double) INFINITY;
+#else
+ /*
+ * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the
+ * largest normal double. We assume forcing an overflow will get us
+ * a true infinity.
+ */
+ return (double) (HUGE_VAL * HUGE_VAL);
+#endif
+}
+
+float
+get_float4_infinity(void)
+{
+#ifdef INFINITY
+ /* C99 standard way */
+ return (float) INFINITY;
+#else
+ /*
+ * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the
+ * largest normal double. We assume forcing an overflow will get us
+ * a true infinity.
+ */
+ return (float) (HUGE_VAL * HUGE_VAL);
+#endif
+}
+
+double
+get_float8_nan(void)
+{
+#ifdef NAN
+ /* C99 standard way */
+ return (double) NAN;
+#else
+ /* Assume we can get a NAN via zero divide */
+ return (double) (0.0 / 0.0);
+#endif
+}
+
+float
+get_float4_nan(void)
+{
+#ifdef NAN
+ /* C99 standard way */
+ return (float) NAN;
+#else
+ /* Assume we can get a NAN via zero divide */
+ return (float) (0.0 / 0.0);
+#endif
+}
+
/*
* Returns -1 if 'val' represents negative infinity, 1 if 'val'
@@ -120,7 +180,7 @@ static int float8_cmp_internal(float8 a, float8 b);
* does not specify that isinf() needs to distinguish between positive
* and negative infinity.
*/
-static int
+int
is_infinite(double val)
{
int inf = isinf(val);
@@ -134,6 +194,7 @@ is_infinite(double val)
return -1;
}
+
/*
* check to see if a float4 val is outside of the FLOAT4_MIN,
* FLOAT4_MAX bounds.
@@ -237,17 +298,17 @@ float4in(PG_FUNCTION_ARGS)
*/
if (strncasecmp(num, "NaN", 3) == 0)
{
- val = NAN;
+ val = get_float4_nan();
endptr = num + 3;
}
else if (strncasecmp(num, "Infinity", 8) == 0)
{
- val = HUGE_VAL;
+ val = get_float4_infinity();
endptr = num + 8;
}
else if (strncasecmp(num, "-Infinity", 9) == 0)
{
- val = -HUGE_VAL;
+ val = - get_float4_infinity();
endptr = num + 9;
}
else
@@ -402,17 +463,17 @@ float8in(PG_FUNCTION_ARGS)
*/
if (strncasecmp(num, "NaN", 3) == 0)
{
- val = NAN;
+ val = get_float8_nan();
endptr = num + 3;
}
else if (strncasecmp(num, "Infinity", 8) == 0)
{
- val = HUGE_VAL;
+ val = get_float8_infinity();
endptr = num + 8;
}
else if (strncasecmp(num, "-Infinity", 9) == 0)
{
- val = -HUGE_VAL;
+ val = - get_float8_infinity();
endptr = num + 9;
}
else