diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2004-03-15 03:29:22 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2004-03-15 03:29:22 +0000 |
commit | 1bc2d544b979164a276f9e6052f0b6d23af59b60 (patch) | |
tree | 5373cea0da5a2587783dd5b805c90427143c7555 /src/backend/utils/adt | |
parent | 89ab5c4abf48de8156b9284dda869f9ea2b2ad44 (diff) | |
download | postgresql-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')
-rw-r--r-- | src/backend/utils/adt/float.c | 99 | ||||
-rw-r--r-- | src/backend/utils/adt/numeric.c | 17 | ||||
-rw-r--r-- | src/backend/utils/adt/timestamp.c | 6 |
3 files changed, 85 insertions, 37 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 diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index f093c414ee5..341bd9cc4c5 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -14,7 +14,7 @@ * Copyright (c) 1998-2003, PostgreSQL Global Development Group * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.71 2004/02/04 01:11:47 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.72 2004/03/15 03:29:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -43,15 +43,6 @@ /* ---------- - * Local definitions - * ---------- - */ -#ifndef NAN -#define NAN (0.0/0.0) -#endif - - -/* ---------- * Local data types * * Numeric values are represented in a base-NBASE floating point format. @@ -1790,7 +1781,7 @@ numeric_float8(PG_FUNCTION_ARGS) Datum result; if (NUMERIC_IS_NAN(num)) - PG_RETURN_FLOAT8(NAN); + PG_RETURN_FLOAT8(get_float8_nan()); tmp = DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(num))); @@ -1811,7 +1802,7 @@ numeric_float8_no_overflow(PG_FUNCTION_ARGS) double val; if (NUMERIC_IS_NAN(num)) - PG_RETURN_FLOAT8(NAN); + PG_RETURN_FLOAT8(get_float8_nan()); val = numeric_to_double_no_overflow(num); @@ -1850,7 +1841,7 @@ numeric_float4(PG_FUNCTION_ARGS) Datum result; if (NUMERIC_IS_NAN(num)) - PG_RETURN_FLOAT4((float4) NAN); + PG_RETURN_FLOAT4(get_float4_nan()); tmp = DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(num))); diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 4fb5f743b03..582bc369d5d 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.100 2004/03/05 02:41:14 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.101 2004/03/15 03:29:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,10 +20,6 @@ #include <errno.h> #include <float.h> #include <limits.h> -/* for finite() on Solaris */ -#ifdef HAVE_IEEEFP_H -#include <ieeefp.h> -#endif #include "access/hash.h" #include "access/xact.h" |